はじめに

NativeScript(NativeScript-Vue) で adamwdraper/Numeral を使って、toLocaleString を実現する方法。

TL;DR

目次

  1. はじめに
  2. TL;DR
  3. 環境・条件
  4. 詳細
    1. 問題: NativeScript は toLocaleString 未対応
  5. So that said, there is not much that can be done on the NativeScript side.. you could look for a custom formatter to handle this case.
  6. つまり、NativeScript側で実行できることはそれほど多くありません。このケースを処理するカスタムフォーマッタを探すことができます。
    1. 解決方法: adamwdraper/Numeral を使う
      1. セットアップ
      2. numeral の使用方法
      3. NativeScript(NativeScript-Vue) で使う
  7. まとめ
  8. 参考文献

環境・条件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.4
BuildVersion: 19E287

$ node -v
v12.7.0

$ npm -v
6.10.3

$ tns --version
6.4.0

$ grep -C1 version package.json
"tns-android": {
"version": "6.0.0"
},
"tns-ios": {
"version": "6.4.2"
}

$ tns plugin
Dependencies:
┌──────────────────────────────┬─────────┐
│ Plugin │ Version │
│ @nativescript/theme │ ^2.2.1 │
│ @vue/devtools │ ^5.0.6 │
│ nativescript-socketio │ ^3.2.1 │
│ nativescript-toasty │ ^1.3.0 │
│ nativescript-vue │ ^2.4.0 │
│ nativescript-vue-devtools │ ^1.2.0 │
│ numeral │ ^2.0.6 │
│ tns-core-modules │ ^6.0.0 │
│ vuex │ ^3.1.1 │
└──────────────────────────────┴─────────┘
Dev Dependencies:
┌────────────────────────────────────┬─────────┐
│ Plugin │ Version │
│ @babel/core │ ^7.0.0 │
│ @babel/preset-env │ ^7.0.0 │
│ babel-loader │ ^8.0.2 │
│ nativescript-dev-webpack │ ^1.0.0 │
│ nativescript-vue-template-compiler │ ^2.0.0 │
│ nativescript-worker-loader │ ~0.9.0 │
│ node-sass │ ^4.9.2 │
│ vue-loader │ ^15.4.0 │
└────────────────────────────────────┴─────────┘

詳細

問題: NativeScript は toLocaleString 未対応

NativeScript(NativeScript-Vue) で toLocaleString を使った数値のフォーマッティングを行おうとしたところ、(現時点の) NativeScript では toLocaleString が機能しなかった。

以下のように toLocaleString() を使っても、1,234,567 とは表示されずにそのまま 1234567 とだけ表示される。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
<Page>
<StackLayout>
<!-- 1,234,567 が期待値だが、そのまま 1234567 と表示される -->
<Label :text="num.toLocaleString()"/>
</StackLayout>
</Page>
</template>

<script >
export default {
data() {
return {
num: 1234567,
};
},
}
</script>

調べたところ、以下の Issue にて同様の内容が議論されている。

toLocaleString() doesn’t localise the number · Issue #8249 · NativeScript/NativeScript

NativeScript uses JavaScriptCore VM (for Android) which has a known issue with toLocalString.

So that said, there is not much that can be done on the NativeScript side.. you could look for a custom formatter to handle this case.

[Google 翻訳]
NativeScriptは、toLocalStringに関する既知の問題があるJavaScriptCore VM(Android用)を使用します。

つまり、NativeScript側で実行できることはそれほど多くありません。このケースを処理するカスタムフォーマッタを探すことができます。

https://github.com/NativeScript/NativeScript/issues/8249#issuecomment-574653384 より引用

ざっくり言うと「JS 標準の toLocaleString() は動作しないし、NativeScript 側でどうにかできる話でもないから別のフォーマッタ使ってね」という感じ。

解決方法: adamwdraper/Numeral を使う

自前で実装するのも面倒だったため、adamwdraper/Numeral を使って解決した。

セットアップ

1
npm i numeral

numeral の使用方法

参考: 公式ドキュメント

フォーマッティング

numeral(<value>).format('') でフォーマッティング。

0,0 で 3桁区切りでの表示。

ただし、小数部がある場合は 切り上げ/切り捨て(おそらく四捨五入)された内容になる。

1
2
3
4
const numeral = require('numeral');

numeral(1234567).format('0,0');
// => '1,234,567'

ただし、小数部がある場合は 切り上げ/切り捨て(おそらく四捨五入)された内容になる。

1
2
3
4
5
numeral(1234567.89).format('0,0');
// => '1,234,568'

numeral(1234567.12).format('0,0');
// => '1,234,567'

小数部も表示したい場合は .0, .00, … を使う。

0,0.0 で 3桁区切り + 小数点第一位までの表示。

1
2
numeral(1234567).format('0,0.0')
// => '1,234,567.0'

必要な場合のみ小数部を表示するには [.] を使う。

0,0[.]000 で 3桁区切り + 小数部がある場合のみ小数点第三位までの表示。

1
2
3
4
5
6
7
8
numeral(1234567).format('0,0[.]000')
// => '1,234,567'

numeral(1234567.123).format('0,0[.]000')
// => '1,234,567.123'

numeral(1234567.8901).format('0,0[.]000')
// => '1,234,567.890'

numeral への入力値が String でも問題なし。(※この場合は主に後述の value を取り出すのに使うと思うが)

1
2
3
4
5
numeral('1234567').format('0,0');
// => '1,234,567'

numeral('1,234,567').format('0');
// => '1234567'

他にも Currency, Bytes, Percentages, Time, Exponential などのフォーマット方法があるので、詳細は Format - 公式ドキュメント を参照。

デフォルト設定

defaultFormat() で、フォーマット方法のデフォルト値を設定可能。

1
2
3
numeral.defaultFormat('0,0[.]0');
numeral('1,234,567.89').format();
// => '1,234,567.9'
値の取り出し

value() で値を Number として取り出し可能。

1
2
numeral('1,234,567.89').value();
// => 1234567.89

NativeScript(NativeScript-Vue) で使う

NativeScript-Vue で使う方法として、自分は mixin として登録して使うようにした。

app/mixins/ToLocaleString.js

1
2
3
4
5
6
7
8
import * as numeral from "numeral";
export default {
methods: {
toLocaleString(num, format='0,0') {
return numeral(num).format(format);
},
},
}

app/main.js

1
2
3
4
...
import ToLocaleString from './mixins/ToLocaleString'
Vue.mixin(ToLocaleString);
...

app/../xxxx.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<Page>
<StackLayout>
<Label :text="toLocaleString(num)"/>
</StackLayout>
</Page>
</template>

<script >
export default {
data() {
return {
num: 1234567,
};
},
}
</script>

まとめ

参考文献

関連記事