directive.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /* @flow */
  2. import { warn, isString, isPlainObject, looseEqual } from './util'
  3. export function bind (el: any, binding: Object, vnode: any): void {
  4. if (!assert(el, vnode)) { return }
  5. t(el, binding, vnode)
  6. }
  7. export function update (el: any, binding: Object, vnode: any, oldVNode: any): void {
  8. if (!assert(el, vnode)) { return }
  9. const i18n: any = vnode.context.$i18n
  10. if (localeEqual(el, vnode) &&
  11. (looseEqual(binding.value, binding.oldValue) &&
  12. looseEqual(el._localeMessage, i18n.getLocaleMessage(i18n.locale)))) { return }
  13. t(el, binding, vnode)
  14. }
  15. export function unbind (el: any, binding: Object, vnode: any, oldVNode: any): void {
  16. const vm: any = vnode.context
  17. if (!vm) {
  18. warn('Vue instance does not exists in VNode context')
  19. return
  20. }
  21. const i18n: any = vnode.context.$i18n || {}
  22. if (!binding.modifiers.preserve && !i18n.preserveDirectiveContent) {
  23. el.textContent = ''
  24. }
  25. el._vt = undefined
  26. delete el['_vt']
  27. el._locale = undefined
  28. delete el['_locale']
  29. el._localeMessage = undefined
  30. delete el['_localeMessage']
  31. }
  32. function assert (el: any, vnode: any): boolean {
  33. const vm: any = vnode.context
  34. if (!vm) {
  35. warn('Vue instance does not exists in VNode context')
  36. return false
  37. }
  38. if (!vm.$i18n) {
  39. warn('VueI18n instance does not exists in Vue instance')
  40. return false
  41. }
  42. return true
  43. }
  44. function localeEqual (el: any, vnode: any): boolean {
  45. const vm: any = vnode.context
  46. return el._locale === vm.$i18n.locale
  47. }
  48. function t (el: any, binding: Object, vnode: any): void {
  49. const value: any = binding.value
  50. const { path, locale, args, choice } = parseValue(value)
  51. if (!path && !locale && !args) {
  52. warn('value type not supported')
  53. return
  54. }
  55. if (!path) {
  56. warn('`path` is required in v-t directive')
  57. return
  58. }
  59. const vm: any = vnode.context
  60. if (choice != null) {
  61. el._vt = el.textContent = vm.$i18n.tc(path, choice, ...makeParams(locale, args))
  62. } else {
  63. el._vt = el.textContent = vm.$i18n.t(path, ...makeParams(locale, args))
  64. }
  65. el._locale = vm.$i18n.locale
  66. el._localeMessage = vm.$i18n.getLocaleMessage(vm.$i18n.locale)
  67. }
  68. function parseValue (value: any): Object {
  69. let path: ?string
  70. let locale: ?Locale
  71. let args: any
  72. let choice: ?number
  73. if (isString(value)) {
  74. path = value
  75. } else if (isPlainObject(value)) {
  76. path = value.path
  77. locale = value.locale
  78. args = value.args
  79. choice = value.choice
  80. }
  81. return { path, locale, args, choice }
  82. }
  83. function makeParams (locale: Locale, args: any): Array<any> {
  84. const params: Array<any> = []
  85. locale && params.push(locale)
  86. if (args && (Array.isArray(args) || isPlainObject(args))) {
  87. params.push(args)
  88. }
  89. return params
  90. }