number.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /* @flow */
  2. import { warn, isString, isObject, includes, numberFormatKeys } from '../util'
  3. export default {
  4. name: 'i18n-n',
  5. functional: true,
  6. props: {
  7. tag: {
  8. type: [String, Boolean, Object],
  9. default: 'span'
  10. },
  11. value: {
  12. type: Number,
  13. required: true
  14. },
  15. format: {
  16. type: [String, Object]
  17. },
  18. locale: {
  19. type: String
  20. }
  21. },
  22. render (h: Function, { props, parent, data }: Object) {
  23. const i18n = parent.$i18n
  24. if (!i18n) {
  25. if (process.env.NODE_ENV !== 'production') {
  26. warn('Cannot find VueI18n instance!')
  27. }
  28. return null
  29. }
  30. let key: ?string = null
  31. let options: ?NumberFormatOptions = null
  32. if (isString(props.format)) {
  33. key = props.format
  34. } else if (isObject(props.format)) {
  35. if (props.format.key) {
  36. key = props.format.key
  37. }
  38. // Filter out number format options only
  39. options = Object.keys(props.format).reduce((acc, prop) => {
  40. if (includes(numberFormatKeys, prop)) {
  41. return Object.assign({}, acc, { [prop]: props.format[prop] })
  42. }
  43. return acc
  44. }, null)
  45. }
  46. const locale: Locale = props.locale || i18n.locale
  47. const parts: NumberFormatToPartsResult = i18n._ntp(props.value, locale, key, options)
  48. const values = parts.map((part, index) => {
  49. const slot: ?Function = data.scopedSlots && data.scopedSlots[part.type]
  50. return slot ? slot({ [part.type]: part.value, index, parts }) : part.value
  51. })
  52. const tag = (!!props.tag && props.tag !== true) || props.tag === false ? props.tag : 'span'
  53. return tag
  54. ? h(tag, {
  55. attrs: data.attrs,
  56. 'class': data['class'],
  57. staticClass: data.staticClass
  58. }, values)
  59. : values
  60. }
  61. }