Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions packages/vue-i18n-core/src/errors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
createCompileError,
CORE_ERROR_CODES_EXTEND_POINT
CORE_ERROR_CODES_EXTEND_POINT,
createCompileError
} from '@intlify/core-base'

import type { BaseError } from '@intlify/shared'
Expand All @@ -26,7 +26,9 @@ export const I18nErrorCodes = {
// not compatible legacy vue-i18n constructor
NOT_COMPATIBLE_LEGACY_VUE_I18N: 33,
// Not available Compostion API in Legacy API mode. Please make sure that the legacy API mode is working properly
NOT_AVAILABLE_COMPOSITION_IN_LEGACY: 34
NOT_AVAILABLE_COMPOSITION_IN_LEGACY: 34,
// duplicate `useI18n` calling
DUPLICATE_USE_I18N_CALLING: 35
} as const

type I18nErrorCodes = (typeof I18nErrorCodes)[keyof typeof I18nErrorCodes]
Expand Down Expand Up @@ -57,5 +59,7 @@ export const errorMessages: { [code: number]: string } = {
[I18nErrorCodes.NOT_COMPATIBLE_LEGACY_VUE_I18N]:
'Not compatible legacy VueI18n.',
[I18nErrorCodes.NOT_AVAILABLE_COMPOSITION_IN_LEGACY]:
'Not available Compostion API in Legacy API mode. Please make sure that the legacy API mode is working properly'
'Not available Compostion API in Legacy API mode. Please make sure that the legacy API mode is working properly',
[I18nErrorCodes.DUPLICATE_USE_I18N_CALLING]:
"Duplicate `useI18n` calling by local scope. Please don't call it on local scope"
}
4 changes: 4 additions & 0 deletions packages/vue-i18n-core/src/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,10 @@ export function useI18n<
setupLifeCycle(i18nInternal, instance, composer)

i18nInternal.__setInstance(instance, composer)
} else {
if (__DEV__ && scope === 'local') {
throw createI18nError(I18nErrorCodes.DUPLICATE_USE_I18N_CALLING)
}
}

return composer as unknown as Composer<
Expand Down
60 changes: 60 additions & 0 deletions packages/vue-i18n-core/test/i18n.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,66 @@ describe('useI18n', () => {
errorMessages[I18nErrorCodes.NOT_INSTALLED_WITH_PROVIDE]
)
})

test(errorMessages[I18nErrorCodes.DUPLICATE_USE_I18N_CALLING], async () => {
const i18n = createI18n<false>({
legacy: false,
locale: 'en',
fallbackLocale: ['en'],
messages: {
en: { hello: 'hello!' }
}
})

const useMyComposable = () => {
const count = ref(0)
const { t } = useI18n({
messages: {
en: {
there: 'hi there! {count}'
}
}
})
return { message: t('there', { count: count.value }) }
}

let error = ''
const App = defineComponent({
setup() {
let message: string = ''
let t: any // eslint-disable-line @typescript-eslint/no-explicit-any
try {
const i18n = useI18n({
messages: {
en: {
hi: 'hi!'
}
}
})
t = i18n.t
const ret = useMyComposable()
message = ret.message
} catch (e: any) {
error = e.message
}
return { t, message, error }
},
template: `
<h1>Root</h1>
<form>
<select v-model="locale">
<option value="en">en</option>
<option value="ja">ja</option>
</select>
</form>
<p>{{ t('hi') }}</p>
<p>{{ message }}</p>
<p>{{ error }}</p>
`
})
await mount(App, i18n as any) // eslint-disable-line @typescript-eslint/no-explicit-any
expect(error).toBe(errorMessages[I18nErrorCodes.DUPLICATE_USE_I18N_CALLING])
})
})

describe('slot reactivity', () => {
Expand Down