99 isPlainObject ,
1010 isObject ,
1111 looseClone ,
12- canUseDateTimeFormat
12+ canUseDateTimeFormat ,
13+ canUseNumberFormat
1314} from './util'
1415import BaseFormatter from './format'
1516import getPathValue from './path'
@@ -32,12 +33,14 @@ export default class VueI18n {
3233 _i18nWatcher : Function
3334 _silentTranslationWarn : boolean
3435 _dateTimeFormatters : Object
36+ _numberFormatters : Object
3537
3638 constructor ( options : I18nOptions = { } ) {
3739 const locale : Locale = options . locale || 'en-US'
3840 const fallbackLocale : Locale = options . fallbackLocale || 'en-US'
3941 const messages : LocaleMessages = options . messages || { }
4042 const dateTimeFormats = options . dateTimeFormats || { }
43+ const numberFormats = options . numberFormats || { }
4144 this . _vm = null
4245 this . _formatter = options . formatter || new BaseFormatter ( )
4346 this . _missing = options . missing || null
@@ -50,20 +53,28 @@ export default class VueI18n {
5053 ? false
5154 : ! ! options . silentTranslationWarn
5255 this . _dateTimeFormatters = { }
56+ this . _numberFormatters = { }
5357
5458 this . _exist = ( message : Object , key : Path ) : boolean => {
5559 if ( ! message || ! key ) { return false }
5660 return ! isNull ( getPathValue ( message , key ) )
5761 }
5862
59- this . _initVM ( { locale, fallbackLocale, messages, dateTimeFormats } )
63+ this . _initVM ( {
64+ locale,
65+ fallbackLocale,
66+ messages,
67+ dateTimeFormats,
68+ numberFormats
69+ } )
6070 }
6171
6272 _initVM ( data : {
6373 locale : Locale ,
6474 fallbackLocale : Locale ,
6575 messages : LocaleMessages ,
66- dateTimeFormats : DateTimeFormats
76+ dateTimeFormats : DateTimeFormats ,
77+ numberFormats : NumberFormats
6778 } ) : void {
6879 const silent = Vue . config . silent
6980 Vue . config . silent = true
@@ -109,6 +120,7 @@ export default class VueI18n {
109120
110121 get messages ( ) : LocaleMessages { return looseClone ( this . _vm . messages ) }
111122 get dateTimeFormats ( ) : DateTimeFormats { return looseClone ( this . _vm . dateTimeFormats ) }
123+ get numberFormats ( ) : NumberFormats { return looseClone ( this . _vm . numberFormats ) }
112124
113125 get locale ( ) : Locale { return this . _vm . locale }
114126 set locale ( locale : Locale ) : void {
@@ -342,10 +354,80 @@ export default class VueI18n {
342354
343355 return this . _d ( value , locale , key )
344356 }
357+
358+ getNumberFormat ( locale : Locale ) : NumberFormat {
359+ return looseClone ( this . _vm . numberFormats [ locale ] )
360+ }
361+
362+ setNumberFormat ( locale : Locale , format : NumberFormat ) : void {
363+ this. _vm . numberFormats [ locale ] = format
364+ }
365+
366+ mergeNumberFormat ( locale : Locale , format : NumberFormat ) : void {
367+ this. _vm . numberFormats [ locale ] = Vue . util . extend ( this . getNumberFormat ( locale ) , format )
368+ }
369+
370+ _n ( value : number , _locale : Locale , key : ?string ) : NumberFormatResult {
371+ if ( process . env . NODE_ENV !== 'production' && ! VueI18n . availabilities . numberFormat ) {
372+ warn ( 'Cannot format a Date value due to not support Intl.NumberFormat.' )
373+ return ''
374+ }
375+
376+ let ret = ''
377+ const numberFormats = this . numberFormats
378+ if ( key ) {
379+ let locale : Locale = _locale
380+ if ( isNull ( numberFormats [ _locale ] [ key ] ) ) {
381+ if ( process . env . NODE_ENV !== 'production' && ! this . _silentTranslationWarn ) {
382+ warn ( `Fall back to the numberFormat of key '${ key } ' with '${ this . fallbackLocale } ' locale.` )
383+ }
384+ locale = this . fallbackLocale
385+ }
386+ const id = `${ locale } __${ key } `
387+ let formatter = this . _numberFormatters [ id ]
388+ const format = numberFormats [ locale ] [ key ]
389+ if ( ! formatter ) {
390+ formatter = this . _numberFormatters [ id ] = Intl . NumberFormat ( locale , format )
391+ }
392+ ret = formatter . format ( value )
393+ } else {
394+ ret = Intl . NumberFormat ( _locale ) . format ( value )
395+ }
396+
397+ return ret
398+ }
399+
400+ n ( value : number , ...args : any ) : NumberFormatResult {
401+ let locale : Locale = this . locale
402+ let key : ?string = null
403+
404+ if ( args . length === 1 ) {
405+ if ( typeof args [ 0 ] === 'string' ) {
406+ key = args [ 0 ]
407+ } else if ( isObject ( args [ 0 ] ) ) {
408+ if ( args [ 0 ] . locale ) {
409+ locale = args [ 0 ] . locale
410+ }
411+ if ( args [ 0 ] . key ) {
412+ key = args [ 0 ] . key
413+ }
414+ }
415+ } else if ( args . length === 2 ) {
416+ if ( typeof args [ 0 ] === 'string' ) {
417+ key = args [ 0 ]
418+ }
419+ if ( typeof args [ 1 ] === 'string' ) {
420+ locale = args [ 1 ]
421+ }
422+ }
423+
424+ return this . _n ( value , locale , key )
425+ }
345426}
346427
347428VueI18n . availabilities = {
348- dateTimeFormat : canUseDateTimeFormat
429+ dateTimeFormat : canUseDateTimeFormat ,
430+ numberFormat : canUseNumberFormat
349431}
350432VueI18n . install = install
351433VueI18n . version = '__VERSION__'
0 commit comments