安装依赖
yarn add element-plus vue-i18n
1. i18n是否可以有同名键?
是可以的,但是同名键会被后加载的内容覆盖。
在 Vue I18n 中,多个语言文件合并时,相同的键名会按照最后合并的语言文件的值覆盖之前的值。例如:
const messages = {
en: {
key1: 'Value from file 1',
},
en: {
key1: 'Value from file 2', // 这个会覆盖前一个文件的 key1
},
};
解决方法:
尽量避免同名键的冲突。
使用命名空间(如页面或组件名)来区分。
2. 拆分国际化配置文件
目录结构示例
src/
├── locales/
│ ├── en/
│ │ ├── home.ts
│ │ ├── about.ts
│ ├── ja/
│ │ ├── home.ts
│ │ ├── about.ts
│ ├── index.ts
各页面的语言文件
- locales/en/home.ts
export default {
home: {
welcome: 'Welcome to the home page',
},
};
- locales/ja/home.ts
export default {
home: {
welcome: 'ホームページへようこそ',
},
};
- locales/en/common.ts
export default {
common: {
changeLanguage: 'Change Language',
},
};
- locales/ja/common.ts
export default {
common: {
changeLanguage: '言語を変更する',
},
};
- 合并语言文件
在 locales/index.ts 中合并拆分的语言文件:
import enHome from './en/home';
import enCommon from './en/common';
import jaHome from './ja/home';
import jaCommon from './ja/common';
const en = {
...enHome,
...enCommon,
};
const ja = {
...jaHome,
...jaCommon,
};
export const messages = {
en,
ja,
};
3. 配置 i18n
在 i18n.ts 中引入合并后的语言文件:
import { createI18n } from 'vue-i18n';
import { messages } from './locales';
const i18n = createI18n({
locale: 'en', // 默认语言
fallbackLocale: 'en', // 备用语言
messages,
});
export default i18n;
4. 使用命名空间解决同名冲突
如果不同页面使用了相同的键名,建议将每个页面的配置放在命名空间下。比如在 home.ts 文件中:
export default {
home: {
welcome: 'Welcome to the home page',
},
};
在 home.ts 文件中:
export default {
home: {
welcome: 'Welcome to the about page',
},
};
使用时需要明确路径:
<p>{{ $t('home.welcome') }}</p>
<p>{{ $t('about.welcome') }}</p>
- 测试效果
在页面组件中使用:
<template>
<div>
<p>{{ $t('home.welcome') }}</p>
<p>{{ $t('common.changeLanguage') }}</p>
</div>
</template>
切换语言:
通过 i18n.global.locale 动态切换:
在@/locales/index.ts中声明
export const switchLanguage = (locale: 'en' | 'ja') => {
i18n.global.locale = locale
}
<div class="switch">
<button @click="switchLanguage('en')">English</button>
<button @click="switchLanguage('ja')">日语</button>
</div>
// 动态更新语言包
function updateLocaleMessages(locale: string, newMessages: Record<string, any>) {
const currentMessages = i18n.global.getLocaleMessage(locale);
i18n.global.setLocaleMessage(locale, {
...currentMessages,
...newMessages, // 合并新内容
});
}
// 使用时调用
updateLocaleMessages('ja', { message: { goodbye: 'さようなら!' } });