1
+ import { watch } from 'vue'
1
2
import { I18nWarnCodes , getWarnMessage } from './warnings'
2
3
import { createI18nError , I18nErrorCodes } from './errors'
3
- import { isString , isPlainObject , isNumber , warn } from '@intlify/shared'
4
+ import {
5
+ isString ,
6
+ isPlainObject ,
7
+ isNumber ,
8
+ warn ,
9
+ inBrowser
10
+ } from '@intlify/shared'
4
11
5
12
import type {
6
13
DirectiveBinding ,
7
14
ObjectDirective ,
8
- ComponentInternalInstance
15
+ WatchStopHandle ,
16
+ ComponentInternalInstance ,
17
+ VNode
9
18
} from 'vue'
10
19
import type { I18n , I18nInternal } from './i18n'
11
20
import type { VueI18nInternal } from './legacy'
@@ -20,6 +29,13 @@ type VTDirectiveValue = {
20
29
plural ?: number
21
30
}
22
31
32
+ declare global {
33
+ interface HTMLElement {
34
+ __i18nWatcher ?: WatchStopHandle
35
+ __composer ?: Composer
36
+ }
37
+ }
38
+
23
39
function getComposer (
24
40
i18n : I18n ,
25
41
instance : ComponentInternalInstance
@@ -73,7 +89,7 @@ function getComposer(
73
89
export type TranslationDirective < T = HTMLElement > = ObjectDirective < T >
74
90
75
91
export function vTDirective ( i18n : I18n ) : TranslationDirective < HTMLElement > {
76
- const bind = (
92
+ const register = (
77
93
el : HTMLElement ,
78
94
{ instance, value, modifiers } : DirectiveBinding
79
95
) : void => {
@@ -88,15 +104,49 @@ export function vTDirective(i18n: I18n): TranslationDirective<HTMLElement> {
88
104
}
89
105
90
106
const parsedValue = parseValue ( value )
91
- // el.textContent = composer.t(...makeParams(parsedValue))
107
+ if ( inBrowser && i18n . global === composer ) {
108
+ // global scope only
109
+ el . __i18nWatcher = watch ( composer . locale , ( ) => {
110
+ instance . $forceUpdate ( )
111
+ } )
112
+ }
113
+ el . __composer = composer
92
114
el . textContent = Reflect . apply ( composer . t , composer , [
93
115
...makeParams ( parsedValue )
94
116
] )
95
117
}
96
118
119
+ const unregister = ( el : HTMLElement ) : void => {
120
+ if ( inBrowser && el . __i18nWatcher ) {
121
+ el . __i18nWatcher ( )
122
+ el . __i18nWatcher = undefined
123
+ delete el . __i18nWatcher
124
+ }
125
+ if ( el . __composer ) {
126
+ el . __composer = undefined
127
+ delete el . __composer
128
+ }
129
+ }
130
+
131
+ const update = ( el : HTMLElement , { value } : DirectiveBinding ) : void => {
132
+ if ( el . __composer ) {
133
+ const composer = el . __composer
134
+ const parsedValue = parseValue ( value )
135
+ el . textContent = Reflect . apply ( composer . t , composer , [
136
+ ...makeParams ( parsedValue )
137
+ ] )
138
+ }
139
+ }
140
+
97
141
return {
98
- beforeMount : bind ,
99
- beforeUpdate : bind
142
+ created : register ,
143
+ unmounted : unregister ,
144
+ beforeUpdate : update ,
145
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
146
+ getSSRProps : ( binding : DirectiveBinding , vnode : VNode ) => {
147
+ // TODO: support SSR
148
+ throw new Error ( 'v-t still is not supported in SSR fully' )
149
+ }
100
150
} as TranslationDirective < HTMLElement >
101
151
}
102
152
0 commit comments