Vue I10 中的重大变更
默认启用 JIT 编译
原因: 可以解决 CSP 问题并支持动态资源
JIT 编译在 v9.3 中引入。默认情况下并未启用。
集成了 vue-i18n 的 Nuxt I18n 已经默认启用了该功能并且稳定。 https://i18n.nuxtjs.org/docs/options/compilation#jit
要在 Vue I18n 中使用此功能,我们必须使用打包工具和 @intlify/unplugin-vue-i18n 来启用 __INTLIFY_JIT_COMPILATION__ 标志。 从 v10 开始,默认情况下不再需要这个标志。
如果你不使用 JIT 编译并准备升级到 v10 或更高版本,你需要重新构建一次应用程序。
关于 JIT 编译的详细信息,请参见 "优化"。
更改传统 API 模式下的 $t 和 t 重载签名
在 Vue I18n v9 中,传统 API 模式和组合 API 模式下的 $t 和 t 重载签名具有不同的接口。
特别是,传统 API 模式下的 $t 和 t 签名比组合 API 模式下的签名少,如下所示:
$t 和 t 重载签名 | 传统 API v9 | 传统 API v10 | 组合 API v9 & v10 |
|---|---|---|---|
$t(key: Key): TranslateResult; | ✅ | ✅ | ✅ |
$t(key: Key, locale: Locale): TranslateResult; | ✅ | - | - |
$t(key: Key, locale: Locale, list: unknown[]): TranslateResult; | ✅ | - | - |
$t(key: Key, locale: Locale, named: NamedValue): TranslateResult; | ✅ | - | - |
$t(key: Key, plural: number): TranslateResult; | - | ✅ | ✅ |
$t(key: Key, plural: number, options: TranslateOptions): TranslateResult; | - | ✅ | ✅ |
$t(key: Key, defaultMsg: string): TranslateResult; | - | ✅ | ✅ |
$t(key: Key, defaultMsg: string, options: TranslateOptions): TranslateResult; | - | ✅ | ✅ |
$t(key: Key, list: unknown[]): TranslateResult; | ✅ | ✅ | ✅ |
$t(key: Key, list: unknown[], plural: number): TranslateResult; | - | ✅ | ✅ |
$t(key: Key, list: unknown[], defaultMsg: string): TranslateResult; | - | ✅ | ✅ |
$t(key: Key, list: unknown[], options: TranslateOptions): TranslateResult; | - | ✅ | ✅ |
$t(key: Key, named: Record<string, unknown>): TranslateResult; | ✅ | ✅ | ✅ |
$t(key: Key, named: NamedValue, plural: number): TranslateResult; | - | ✅ | ✅ |
$t(key: Key, named: NamedValue, defaultMsg: string): TranslateResult; | - | ✅ | ✅ |
$t(key: Key, named: NamedValue, options: TranslateOptions): TranslateResult; | - | ✅ | ✅ |
t(key: Key): TranslateResult; | ✅ | ✅ | ✅ |
t(key: Key, locale: Locale): TranslateResult; | ✅ | - | - |
t(key: Key, locale: Locale, list: unknown[]): TranslateResult; | ✅ | - | - |
t(key: Key, locale: Locale, named: Record<string, unknown>): TranslateResult; | ✅ | - | - |
t(key: Key, plural: number): TranslateResult; | - | ✅ | ✅ |
t(key: Key, plural: number, options: TranslateOptions<Locales>): TranslateResult; | - | ✅ | ✅ |
t(key: Key, defaultMsg: string): TranslateResult; | - | ✅ | ✅ |
t(key: Key, defaultMsg: string, options: TranslateOptions<Locales>): TranslateResult; | - | ✅ | ✅ |
t(key: Key, list: unknown[]): TranslateResult; | ✅ | ✅ | ✅ |
t(key: Key, list: unknown[], plural: number): TranslateResult; | - | ✅ | ✅ |
t(key: Key, list: unknown[], defaultMsg: string): TranslateResult; | - | ✅ | ✅ |
t(key: Key, list: unknown[], options: TranslateOptions<Locales>): TranslateResult; | - | ✅ | ✅ |
t(key: Key, named: Record<string, unknown>): TranslateResult; | ✅ | ✅ | ✅ |
t(key: Key, named: NamedValue, plural: number): TranslateResult; | - | ✅ | ✅ |
t(key: Key, named: NamedValue, defaultMsg: string): TranslateResult; | - | ✅ | ✅ |
t(key: Key, named: NamedValue, options: TranslateOptions<Locales>): TranslateResult; | - | ✅ | ✅ |
从 v10 开始,传统 API 模式可以使用与组合 API 模式相同的 $t 和 t 重载签名。
原因: 这样迁移后,在迁移到组合 API 模式时,我们有时会因为不同的签名而陷入陷阱。
如果你在传统 API 模式下使用以下 API,由于重大变更,你必须更改签名:
$t(key: Key, locale: Locale): TranslateResult;$t(key: Key, locale: Locale, list: unknown[]): TranslateResult;$t(key: Key, locale: Locale, named: NamedValue): TranslateResult;t(key: Key, locale: Locale): TranslateResult;t(key: Key, locale: Locale, list: unknown[]): TranslateResult;t(key: Key, locale: Locale, named: NamedValue): TranslateResult;
$t(key: Key, locale: Locale): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $t('message.hello', 'ja') }}</p>
</template>Vue I18n v10 或更高版本:
使用 $t(key: Key, list: unknown[], options: TranslateOptions): TranslateResult; 或 $t(key: Key, named: NamedValue, options: TranslateOptions): TranslateResult;
<template>
<p>{{ $t('message.hello', {}, { locale: 'ja' }) }}</p>
</template>$t(key: Key, locale: Locale, list: unknown[]): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $t('message.hello', 'ja', ['dio']) }}</p>
</template>Vue I18n v10 或更高版本:
使用 $t(key: Key, list: unknown[], options: TranslateOptions): TranslateResult;
<template>
<p>{{ $t('message.hello', ['dio'], { locale: 'ja' }) }}</p>
</template>$t(key: Key, locale: Locale, named: NamedValue): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $t('message.hello', 'ja', { name: 'dio' }) }}</p>
</template>Vue I18n v10 或更高版本:
使用 $t(key: Key, named: NamedValue, options: TranslateOptions): TranslateResult;
<template>
<p>{{ $t('message.hello', { name: 'dio' }, { locale: 'ja' }) }}</p>
</template>t(key: Key, locale: Locale): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.t('message.hello', 'ja'))Vue I18n v10 或更高版本:
使用 t(key: Key, list: unknown[], options: TranslateOptions): TranslateResult; 或 t(key: Key, named: NamedValue, options: TranslateOptions): TranslateResult;
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.t('message.hello', {}, { locale: 'ja' }))t(key: Key, locale: Locale, list: unknown[]): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.t('message.hello', 'ja', ['dio']))Vue I18n v10 或更高版本:
使用 t(key: Key, list: unknown[], options: TranslateOptions): TranslateResult;
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.t('message.hello', ['dio'], { locale: 'ja' }))t(key: Key, locale: Locale, named: NamedValue): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.t('message.hello', 'ja', { name: 'dio' }))Vue I18n v10 或更高版本:
使用 t(key: Key, named: NamedValue, options: TranslateOptions): TranslateResult;
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.t('message.hello', { name: 'dio' }, { locale: 'ja' }))废弃传统 API 模式下的 tc 和 $tc
以下 API 在 v10 中被废弃:
tc(key: Key | ResourceKeys): TranslateResult;tc(key: Key | ResourceKeys, locale: Locales | Locale): TranslateResult;tc(key: Key | ResourceKeys, list: unknown[]): TranslateResult;tc(key: Key | ResourceKeys, named: Record<string, unknown>): TranslateResult;tc(key: Key | ResourceKeys, choice: number): TranslateResult;tc(key: Key | ResourceKeys, choice: number, locale: Locales | Locale): TranslateResult;tc(key: Key | ResourceKeys, choice: number, list: unknown[]): TranslateResult;tc(key: Key | ResourceKeys, choice: number, named: Record<string, unknown>): TranslateResult;$tc(key: Key): TranslateResult;$tc(key: Key, locale: Locale): TranslateResult;$tc(key: Key, list: unknown[]): TranslateResult;$tc(key: Key, named: Record<string, unknown>): TranslateResult;$tc(key: Key, choice: number): TranslateResult;$tc(key: Key, choice: number, locale: Locale): TranslateResult;$tc(key: Key, choice: number, list: unknown[]): TranslateResult;$tc(key: Key, choice: number, named: Record<string, unknown>): TranslateResult;
原因: 传统 API 模式下的 t 和 $t 支持复数接口,所以它们可以被替换。
在 v10 中,tc 和 $tc 仍然存在,以便于迁移。这些将在 v11 中完全删除。
如果你使用它们,Vue I18n 会在应用程序中输出控制台警告。
tc(key: Key | ResourceKeys): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.tc('banana'))Vue I18n v10 或更高版本:
使用 t(key: Key | ResourceKeys, plural: number): TranslateResult;
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.t('banana', 1))tc(key: Key | ResourceKeys, locale: Locales | Locale): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.tc('banana', 'ja'))Vue I18n v10 或更高版本:
使用 t(key: Key | ResourceKeys, plural: number, options: TranslateOptions<Locales>): TranslateResult;
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.t('banana', 1, { locale: 'ja' }))tc(key: Key | ResourceKeys, list: unknown[]): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.tc('banana', ['dio']))Vue I18n v10 或更高版本:
使用 t(key: Key | ResourceKeys, list: unknown[], plural: number): TranslateResult;
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.t('banana', ['dio'], 1))tc(key: Key | ResourceKeys, named: Record<string, unknown>): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.tc('banana', { name: 'dio' }))Vue I18n v10 或更高版本:
使用 t(key: Key | ResourceKeys, named: NamedValue, plural: number): TranslateResult;
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.t('banana', { name: 'dio' }, 1))tc(key: Key | ResourceKeys, choice: number): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.tc('banana', 2))Vue I18n v10 或更高版本:
使用 t(key: Key | ResourceKeys, plural: number): TranslateResult;
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.t('banana', 2))tc(key: Key | ResourceKeys, choice: number, locale: Locales | Locale): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.tc('banana', 2, 'ja'))Vue I18n v10 或更高版本:
使用 t(key: Key | ResourceKeys, plural: number, options: TranslateOptions<Locales>): TranslateResult;
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.t('banana', 2, { locale: 'ja' }))tc(key: Key | ResourceKeys, choice: number, list: unknown[]): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.tc('banana', 2, ['dio']))Vue I18n v10 或更高版本:
使用 t(key: Key | ResourceKeys, list: unknown[], plural: number): TranslateResult;
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.t('banana', ['dio'], 2))tc(key: Key | ResourceKeys, choice: number, named: Record<string, unknown>): TranslateResult;
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.tc('banana', 2, { name: 'dio' }))Vue I18n v10 或更高版本:
使用 t(key: Key | ResourceKeys, named: NamedValue, plural: number): TranslateResult;
const i18n = createI18n({
legacy: true,
// 某些选项 ...
})
console.log(i18n.global.t('banana', { name: 'dio' }, 2))$tc(key: Key): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $tc('banana') }}</p>
</template>Vue I18n v10 或更高版本:
使用 $t(key: Key, plural: number): TranslateResult;
<template>
<p>{{ $t('banana', 1) }}</p>
</template>$tc(key: Key, locale: Locale): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $tc('banana', 'ja') }}</p>
</template>Vue I18n v10 或更高版本:
使用 $t(key: Key, plural: number, options: TranslateOptions): TranslateResult;
<template>
<p>{{ $t('banana', 1, { locale: 'ja' }) }}</p>
</template>$tc(key: Key, list: unknown[]): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $tc('banana', ['dio']) }}</p>
</template>Vue I18n v10 或更高版本:
使用 $t(key: Key, list: unknown[], plural: number): TranslateResult;
<template>
<p>{{ $t('banana', ['dio'], 1) }}</p>
</template>$tc(key: Key, named: Record<string, unknown>): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $tc('banana', { name: 'dio' }) }}</p>
</template>Vue I18n v10 或更高版本:
使用 $t(key: Key, named: NamedValue, plural: number): TranslateResult;
<template>
<p>{{ $t('banana', { name: 'dio' }, 1) }}</p>
</template>$tc(key: Key, choice: number): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $tc('banana', 2) }}</p>
</template>Vue I18n v10 或更高版本:
使用 $t(key: Key, plural: number): TranslateResult;
<template>
<p>{{ $t('banana', 2) }}</p>
</template>$tc(key: Key, choice: number, locale: Locale): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $tc('banana', 2, 'ja') }}</p>
</template>Vue I18n v10 或更高版本:
使用 $t(key: Key, plural: number, options: TranslateOptions): TranslateResult;
<template>
<p>{{ $t('banana', 2, { locale: 'ja' }) }}</p>
</template>$tc(key: Key, choice: number, list: unknown[]): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $tc('banana', 2, ['dio']) }}</p>
</template>Vue I18n v10 或更高版本:
使用 $t(key: Key, list: unknown[], plural: number): TranslateResult;
<template>
<p>{{ $t('banana', ['dio'], 2) }}</p>
</template>$tc(key: Key, choice: number, named: Record<string, unknown>): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $tc('banana', 2, { name: 'dio' }) }}</p>
</template>Vue I18n v10 或更高版本:
使用 $t(key: Key, named: NamedValue, plural: number): TranslateResult;
<template>
<p>{{ $t('banana', { name: 'dio' }, 2) }}</p>
</template>移除模块 % 语法
在 v10 中不再支持使用模块 % 的命名插值。
原因: 模块语法已在 v9 中被废弃并有警告。
迁移方法
你可以使用 eslint-plugin-vue-i18n。
eslint-plugin-vue-i18n 具有 @intlify/vue-i18n/no-deprecated-modulo-syntax 规则。 https://eslint-plugin-vue-i18n.intlify.dev/rules/no-deprecated-modulo-syntax.html
你可以使用 eslint --fix 进行修复。
在升级到 vue-i18n v10 之前,你必须先使用 eslint 进行迁移。
移除 vue-i18n-bridge
原因: vue-i18n-bridge 是一个用于从 Vue 2 迁移到 Vue 3 的 vue-i18n 桥接库,而 Vue 2 已不再处于生命周期末期。
移除 allowComposition 选项
原因: 此选项已在 v10 中警告即将被移除。文档指出,https://vue-i18n.intlify.dev/guide/migration/vue3.html#about-supporting
此选项是为了在 v9 中支持从传统 API 迁移到组合 API 而添加的。
移除传统 API 中的 formatter 选项
原因: 此选项已在 v9 中警告被废弃。
移除传统 API 中的 preserveDirectiveContent 选项
原因: 此选项已在 v9 中警告被废弃。
移除 v-t 指令中的 preserve 修饰符代码
原因: 此选项已在 v9 中警告被废弃。
移除传统 API 中的 getChoiceIndex
原因: 此选项已在 v9 中警告被废弃。
移除翻译组件 <i18n> v8.x 兼容性
原因: 此选项已在 v9 中警告被废弃。
移除 te 行为 v8.x 兼容性
原因: 此选项已在 v9 中警告被废弃。
此选项是在这个问题中引入的,用于在 v9 中支持 te 行为 v8.x 兼容性。