Code前端首页关于Code前端联系我们

做项目时碰到多语言需求,Vue2 里咋用 i18n 实现国际化?从安装配置到组件调用、语言切换这些实战细节,这篇一步步讲清楚,新手也能跟着搞定~

terry 10小时前 阅读数 10 #Vue
文章标签 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 文件,步骤如下:

  1. 引入 Vue 和 VueI18n:
    import Vue from 'vue'
    import VueI18n from 'vue-i18n'
    Vue.use(VueI18n) // 注册插件
  2. 配置多语言消息(以中英文为例):
    const messages = {
    en: {
     home: {
       title: 'Home Page',
       desc: 'This is a demo for i18n'
     },
     greet: 'Hello, {name}' // 带变量的文本
    },
    zh: {
     home: {
       title: '首页',
       desc: '这是i18n的示例'
     },
     greet: '你好,{name}'
    }
    }
  3. 创建 i18n 实例并指定默认语言:
    const i18n = new VueI18n({
    locale: 'zh', // 默认显示中文
    messages // 上面配置的多语言消息
    })
  4. 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.jsonsrc/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前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门