@@ -32,7 +32,8 @@ import { I18nErrorCodes, createI18nError } from './errors'
32
32
import {
33
33
EnableEmitter ,
34
34
DisableEmitter ,
35
- InejctWithOption ,
35
+ DisposeSymbol ,
36
+ InejctWithOptionSymbol ,
36
37
LegacyInstanceSymbol ,
37
38
__VUE_I18N_BRIDGE__
38
39
} from './symbols'
@@ -81,7 +82,13 @@ import type {
81
82
ComposerOptions ,
82
83
ComposerInternalOptions
83
84
} from './composer'
84
- import type { VueI18n , VueI18nOptions , VueI18nInternal } from './legacy'
85
+ import type {
86
+ VueI18n ,
87
+ VueI18nOptions ,
88
+ VueI18nInternal ,
89
+ VueI18nExtender
90
+ } from './legacy'
91
+ import type { Disposer } from './types'
85
92
86
93
declare module 'vue' {
87
94
// eslint-disable-next-line
@@ -251,12 +258,17 @@ export interface I18n<
251
258
dispose ( ) : void
252
259
}
253
260
261
+ export type ComposerExtender = ( composer : Composer ) => Disposer | undefined
262
+
254
263
/**
264
+ * The hooks that give to extend Composer (Composition API) and VueI18n instance (Options API).
265
+ * This hook is mainly for vue-i18n-routing and nuxt i18n.
266
+ *
255
267
* @internal
256
268
*/
257
269
type ExtendHooks = {
258
- __composerExtend ?: ( composer : Composer ) => void
259
- __vueI18nExtend ?: ( vueI18n : VueI18n ) => void
270
+ __composerExtend ?: ComposerExtender
271
+ __vueI18nExtend ?: VueI18nExtender
260
272
}
261
273
262
274
/**
@@ -291,8 +303,8 @@ export interface I18nInternal<
291
303
instance : Instance
292
304
) : void
293
305
__deleteInstance ( component : ComponentInternalInstance ) : void
294
- __composerExtend ?: Required < ExtendHooks > [ '__composerExtend' ]
295
- __vueI18nExtend ?: Required < ExtendHooks > [ '__vueI18nExtend' ]
306
+ __composerExtend ?: ComposerExtender
307
+ __vueI18nExtend ?: VueI18nExtender
296
308
}
297
309
298
310
/**
@@ -584,6 +596,8 @@ export function createI18n(options: any = {}, VueI18nLegacy?: any): any {
584
596
// set composer & vuei18n extend hook options from plugin options
585
597
if ( isPlainObject ( options [ 0 ] ) ) {
586
598
const opts = options [ 0 ] as ExtendHooks
599
+ // Plugin options cannot be passed directly to the function that creates Composer & VueI18n,
600
+ // so we keep it temporary
587
601
; ( i18n as unknown as I18nInternal ) . __composerExtend =
588
602
opts . __composerExtend
589
603
; ( i18n as unknown as I18nInternal ) . __vueI18nExtend =
@@ -897,7 +911,9 @@ export function useI18n<
897
911
898
912
composer = createComposer ( composerOptions , _legacyVueI18n ) as Composer
899
913
if ( i18nInternal . __composerExtend ) {
900
- i18nInternal . __composerExtend ( composer )
914
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
915
+ ; ( composer as any ) [ DisposeSymbol ] =
916
+ i18nInternal . __composerExtend ( composer )
901
917
}
902
918
setupLifeCycle ( i18nInternal , instance , composer )
903
919
@@ -1044,7 +1060,7 @@ function getComposer(
1044
1060
if (
1045
1061
useComponent &&
1046
1062
composer &&
1047
- ! ( composer as any ) [ InejctWithOption ] // eslint-disable-line @typescript-eslint/no-explicit-any
1063
+ ! ( composer as any ) [ InejctWithOptionSymbol ] // eslint-disable-line @typescript-eslint/no-explicit-any
1048
1064
) {
1049
1065
composer = null
1050
1066
}
@@ -1151,6 +1167,9 @@ function setupLifeCycle(
1151
1167
} , target )
1152
1168
1153
1169
onUnmounted ( ( ) => {
1170
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1171
+ const _composer = composer as any
1172
+
1154
1173
// remove composer instance from DOM for intlify-devtools
1155
1174
if (
1156
1175
( __DEV__ || __FEATURE_PROD_VUE_DEVTOOLS__ ) &&
@@ -1159,12 +1178,17 @@ function setupLifeCycle(
1159
1178
target . vnode . el . __VUE_I18N__
1160
1179
) {
1161
1180
emitter && emitter . off ( '*' , addTimelineEvent )
1162
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1163
- const _composer = composer as any
1164
1181
_composer [ DisableEmitter ] && _composer [ DisableEmitter ] ( )
1165
1182
delete target . vnode . el . __VUE_I18N__
1166
1183
}
1167
1184
i18n . __deleteInstance ( target )
1185
+
1186
+ // dispose extended resources
1187
+ const dispose = _composer [ DisposeSymbol ]
1188
+ if ( dispose ) {
1189
+ dispose ( )
1190
+ delete _composer [ DisposeSymbol ]
1191
+ }
1168
1192
} , target )
1169
1193
}
1170
1194
}
@@ -1656,12 +1680,7 @@ const globalExportMethods = !__LITE__
1656
1680
? [ 't' , 'rt' , 'd' , 'n' , 'tm' , 'te' ]
1657
1681
: [ 't' ]
1658
1682
1659
- type GlobalInjectionReleaseHandler = ( ) => void
1660
-
1661
- function injectGlobalFields (
1662
- app : App ,
1663
- composer : Composer
1664
- ) : GlobalInjectionReleaseHandler {
1683
+ function injectGlobalFields ( app : App , composer : Composer ) : Disposer {
1665
1684
const i18n = Object . create ( null )
1666
1685
globalExportProps . forEach ( prop => {
1667
1686
const desc = Object . getOwnPropertyDescriptor ( composer , prop )
@@ -1695,7 +1714,7 @@ function injectGlobalFields(
1695
1714
Object . defineProperty ( app . config . globalProperties , `$${ method } ` , desc )
1696
1715
} )
1697
1716
1698
- const release = ( ) => {
1717
+ const dispose = ( ) => {
1699
1718
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1700
1719
delete ( app as any ) . config . globalProperties . $i18n
1701
1720
globalExportMethods . forEach ( method => {
@@ -1704,7 +1723,7 @@ function injectGlobalFields(
1704
1723
} )
1705
1724
}
1706
1725
1707
- return release
1726
+ return dispose
1708
1727
}
1709
1728
1710
1729
function injectGlobalFieldsForBridge (
0 commit comments