做项目时碰到多语言需求,Vue2 里咋用 i18n 实现国际化?从安装配置到组件调用、语言切换这些实战细节,这篇一步步讲清楚,新手也能跟着搞定~
Vue2 里咋装 i18n 依赖?
首先得选对版本!Vue2 要搭配 vue-i18n@8.x 版本,因为更高版本(9.x+)是给 Vue3 用的,版本不对容易报各种错。
装依赖很简单:用 npm 的话,终端输 npm install vue-i18n@8 --save;用 yarn 就输 yarn add vue-i18n@8。
装完得初始化 i18n 实例,推荐在 src 目录下新建 i18n.js 文件,步骤如下:
- 引入 Vue 和 VueI18n:
import Vue from 'vue' import VueI18n from 'vue-i18n' Vue.use(VueI18n) // 注册插件
- 配置多语言消息(以中英文为例):
const messages = { en: { home: { title: 'Home Page', desc: 'This is a demo for i18n' }, greet: 'Hello, {name}' // 带变量的文本 }, zh: { home: { title: '首页', desc: '这是i18n的示例' }, greet: '你好,{name}' } } - 创建 i18n 实例并指定默认语言:
const i18n = new VueI18n({ locale: 'zh', // 默认显示中文 messages // 上面配置的多语言消息 }) - 在
main.js里把 i18n 挂到 Vue 实例:import Vue from 'vue' import App from './App.vue' import i18n from './i18n' // 引入上面的i18n.js
new Vue({ i18n, // 注入i18n实例 render: h => h(App) }).$mount('#app')
### 二、怎么在组件里用国际化文本?
配置好后,组件里主要靠 `$t` 方法调用多语言文本,分三种场景:
#### 1. 纯文本插值
模板里直接用 `{{ $t('键名') }}`,比如要显示“首页”,对应 `zh.home.title`,就写:
```vue
<template>
<div>{{ $t('home.title') }}</div>
</template>
带变量的文本
如果文本里有动态内容(比如用户名),messages 里用占位符(像 {name}),然后调用时传对象。greet 字段:
<template>
<!-- 渲染成“你好,小明” -->
<div>{{ $t('greet', { name: '小明' }) }}</div>
</template>
JS 里调用(比如计算属性、方法)
在 script 里用 this.$t('键名'),比如做个动态标题的计算属性:
<script>
export default {
computed: {
pageTitle() {
return this.$t('home.title') // 对应“首页”或“Home Page”
}
}
}
</script>
带 HTML 标签的文本
如果文本里需要包含 HTML(比如加粗、换行),得用 v-html 配合 $t,先在 messages 里写带标签的字符串:
zh: {
tip: '<strong>重要</strong>提示'
}
然后模板里这么用:
<template>
<div v-html="$t('tip')"></div> <!-- 渲染成“<strong>重要</strong>提示” -->
</template>
⚠️ 注意:这种方式要警惕 XSS 攻击,别把用户输入的内容直接塞进来!
多语言切换咋实现?
核心是修改 i18n.locale 属性,再配合持久化(刷新后保留语言)。
切换逻辑(按钮点击示例)
在组件里加个切换按钮,点击时切换 locale:
<template>
<button @click="switchLang">
{{ $i18n.locale === 'zh' ? '切换到英文' : '切换到中文' }}
</button>
</template>
<script>
export default {
methods: {
switchLang() {
// 切换语言
this.$i18n.locale = this.$i18n.locale === 'zh' ? 'en' : 'zh'
// 存到localStorage,刷新后保留
localStorage.setItem('lang', this.$i18n.locale)
}
}
}
</script>
刷新后保留语言
上面切换时存了 localStorage,但初始化 i18n 时得先读这个值,修改 i18n.js 里的默认语言:
// 优先读localStorage,没有则用'zh'
const defaultLang = localStorage.getItem('lang') || 'zh'
const i18n = new VueI18n({
locale: defaultLang,
messages
})
和异步加载语言包咋处理?
如果语言包很大(比如几十种语言),或者想按需加载,得用动态导入和异步处理。
拆分语言包为单独 JSON 文件
把每种语言的配置放到单独文件,src/lang/en.json、src/lang/zh.json,以 zh.json 为例:
{
"home": {: "首页",
"desc": "这是i18n的示例"
},
"greet": "你好,{name}"
}
异步加载语言包(切换时加载)
修改切换语言的方法,用 import() 动态加载对应语言包,再合并到 messages:
<script>
export default {
methods: {
async switchLang() {
const newLang = this.$i18n.locale === 'zh' ? 'en' : 'zh'
// 动态导入语言包
const langMessages = await import(`@/lang/${newLang}.json`)
// 把新语言包设置到i18n里
this.$i18n.setLocaleMessage(newLang, langMessages.default)
// 切换语言
this.$i18n.locale = newLang
// 持久化
localStorage.setItem('lang', newLang)
}
}
}
</script>
的国际化(比如用户自定义文本)
如果项目里有用户输入的多语言内容(比如商品名称要支持中英),通常后端会存成键值对(如 { en: 'Product', zh: '商品' }),前端渲染时,用当前语言取对应值:
// 假设后端返回的字段是multiLangName
const multiLangName = { en: 'Product', zh: '商品' }
// 渲染时
this.$t(multiLangName[this.$i18n.locale])
// 或者更灵活的方式:后端存key,前端用$t(key),但需要提前把用户内容注入messages
和 UI 库(Element UI)结合咋做?
Element UI 本身有自己的国际化配置,得和项目的 i18n 同步语言。
引入 Element UI 及对应语言包
先装 Element UI:npm i element-ui -S,然后在 main.js 引入:
import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css' import locale from 'element-ui/lib/locale' // Element的国际化核心 import enLocale from 'element-ui/lib/locale/lang/en' // 英文包 import zhLocale from 'element-ui/lib/locale/lang/zh-CN' // 中文包
同步项目语言和 Element 语言
初始化时,让 Element 语言和项目默认语言一致:
const defaultLang = localStorage.getItem('lang') || 'zh'
// 设置Element的语言
locale.use(defaultLang === 'en' ? enLocale : zhLocale)
切换语言时,同时更新 Element 的语言:
<script>
export default {
methods: {
switchLang() {
const newLang = this.$i18n.locale === 'zh' ? 'en' : 'zh'
this.$i18n.locale = newLang
// 同步Element UI的语言
locale.use(newLang === 'en' ? enLocale : zhLocale)
localStorage.setItem('lang', newLang)
}
}
}
</script>
这样 Element 的组件(比如日期选择器、弹窗)的语言就会和项目整体一致啦~
实战中容易踩的坑有哪些?
踩过这些坑,能少走很多弯路:
版本不对导致报错
一定要装 vue-i18n@8.x!要是装了 vue-i18n@9+,Vue2 会报“无法找到导出”“语法错误”之类的错,因为高版本只支持 Vue3。
嵌套键找不到内容
如果用 $t('a.b.c'),但 messages.a.b.c 没定义,$t 会直接返回 'a.b.c'(而不是空或报错),所以要仔细检查 messages 的层级结构,确保每个键都存在。
切换语言后页面没更新
这是因为 locale 没做成响应式数据,Vue2 里,必须直接修改 this.$i18n.locale,不能自己搞个变量存语言再同步(this.currentLang 再赋值给 this.$i18n.locale),否则 Vue 无法检测到变化,页面就不更新。
动态加载语言包时闪现旧内容
异步加载语言包时,要等加载完成再切换 locale,用 async/await 确保顺序:先加载语言包,再设置 locale,避免用户看到“半切换”的状态。
第三方组件国际化不同步
除了 Element UI,像 Vant、Ant Design Vue 这些 UI 库也有自己的 i18n 逻辑,切换语言时,要去看它们的文档,把语言切换逻辑和项目的 i18n 绑定,否则 UI 组件还是默认语言,体验很割裂。
把这些步骤走通,Vue2 项目的国际化基本就稳了~从基础配置到组件调用、语言切换,再到和 UI 库配合,每个环节都有细节要注意,但只要跟着例子一步步来,多语言需求就能轻松落地,要是实战中碰到其他问题,评论区交流呀~
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网



