做项目时碰到多语言需求,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前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。