一文详解如何在Vue3项目中实现国际化功能

 更新时间:2026年06月18日 09:15:44   作者:阿猫的故乡  
本文详细介绍了在Vue3项目中实现国际化功能的方法,包括安装vue-i18n库、创建语言包文件、在模板中使用国际化文案及以及实现语言切换功能,通过使用vue-i;8n库,可以轻松实现中英文切换,并同步更新ElementPlus组件文字,简化了多语言管理,需要的朋友可以参考下

一、先扯两句:国际化到底在干啥?

你有没有遇到过这种需求:产品经理跑过来说“咱们这个系统,国内用户看中文,海外用户看英文,你给搞一下”。

如果你写死中文,那就得把整个项目翻一遍,把所有中文字符串都手动替换成英文,想想都头大。

国际化的思路是:把所有文案都抽出来放进一个“字典”里,根据当前语言去字典里取对应的翻译。 语言一变,所有页面上的文字自动跟着变。

Vue 生态里有个专门干这事的库叫 vue-i18n,今天咱们就用它从零搭一个中英文切换系统,顺便把 Element Plus 的多语言也一并搞定。

二、第一步:装包 + 基本配置

2.1 安装 vue-i18n

打开终端,在项目根目录执行:

npm install vue-i18n@9

这里用 @9 是因为 v9 版本对应 Vue3,v8 是给 Vue2 用的。

2.2 创建语言包文件

在 src 下新建一个 locales(或 lang)文件夹,用来放语言包。

先建两个文件:中文语言包 zh.js 和英文语言包 en.js

src/locales/zh.js

// 中文语言包
// 这里把所有页面上会出现的文字都定义好
export default {
  // 通用
  common: {
    confirm: '确定',
    cancel: '取消',
    save: '保存',
    delete: '删除',
    search: '搜索',
    reset: '重置',
  },
  // 登录页
  login: {
    title: '用户登录',
    username: '用户名',
    password: '密码',
    remember: '记住密码',
    submit: '登 录',
    usernamePlaceholder: '请输入用户名',
    passwordPlaceholder: '请输入密码',
    success: '登录成功',
    failed: '登录失败,请检查用户名和密码',
  },
  // 导航菜单
  menu: {
    home: '首页',
    user: '用户管理',
    article: '文章管理',
    settings: '系统设置',
  },
  // 用户管理页
  user: {
    add: '新增用户',
    edit: '编辑用户',
    deleteConfirm: '确定要删除该用户吗?',
    deleteSuccess: '删除成功',
  },
}

src/locales/en.js

// 英文语言包
export default {
  common: {
    confirm: 'Confirm',
    cancel: 'Cancel',
    save: 'Save',
    delete: 'Delete',
    search: 'Search',
    reset: 'Reset',
  },
  login: {
    title: 'User Login',
    username: 'Username',
    password: 'Password',
    remember: 'Remember me',
    submit: 'Login',
    usernamePlaceholder: 'Please input username',
    passwordPlaceholder: 'Please input password',
    success: 'Login successful',
    failed: 'Login failed, please check username and password',
  },
  menu: {
    home: 'Home',
    user: 'User Management',
    article: 'Article Management',
    settings: 'System Settings',
  },
  user: {
    add: 'Add User',
    edit: 'Edit User',
    deleteConfirm: 'Are you sure to delete this user?',
    deleteSuccess: 'Deleted successfully',
  },
}

为什么要这样组织?

  • 把文案按模块分组(common、login、menu 等),找起来方便,不会几百个翻译全挤在一起。
  • 键名用英文,方便在代码里通过 $t('login.title') 这种路径访问。

2.3 创建 i18n 实例并挂载到 Vue 上

新建 src/locales/index.js,在这里创建 i18n 实例。

// src/locales/index.js
import { createI18n } from 'vue-i18n'
import zh from './zh.js'
import en from './en.js'
// 创建 i18n 实例
const i18n = createI18n({
  // legacy: false 是必须的,它表示使用组合式 API 模式
  legacy: false,
  // 默认语言
  locale: 'zh',
  // 如果当前语言没有对应的翻译键,就用备用语言来兜底
  fallbackLocale: 'zh',
  // 所有的语言包都注册在这里
  messages: {
    zh,  // 中文
    en,  // 英文
  },
})
export default i18n

逐行解释:

  • legacy: false:让 i18n 支持 <script setup> 里的组合式 API,否则只能用 this.$t()
  • locale:当前激活的语言,默认 'zh' 中文。
  • fallbackLocale:如果某个翻译键在英文包里忘写了,就用中文的代替,不至于页面上出现空白或报错。
  • messages:把所有语言包都放进来,键名(zhen)对应后面切换语言时的语言标识。

在 main.js 里注册 i18n:

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import i18n from './locales'  // 引入 i18n
const app = createApp(App)
app.use(i18n)   // 挂载
app.mount('#app')

三、第二步:在模板里使用国际化文案

3.1 用$t函数在模板里翻译

$t 是 i18n 提供的全局翻译函数,用法类似取对象的路径。

<template>
  <div>
    <!-- 翻译登录页的标题 -->
    <h2>{{ $t('login.title') }}</h2>
    <!-- 翻译通用按钮 -->
    <button>{{ $t('common.confirm') }}</button>
    <button>{{ $t('common.cancel') }}</button>
    <!-- 翻译带占位符的,可以传参数 -->
    <p>{{ $t('login.success') }}</p>
  </div>
</template>

效果: 当前语言是中文时显示中文,是英文时显示英文。

3.2 在<script setup>里使用

<script setup> 里没有 this.$t,要用 useI18n 拿到 t 函数。

<script setup>
import { useI18n } from 'vue-i18n'
// useI18n 返回一个对象,里面有 t 函数
const { t } = useI18n()
// 在 JS 里翻译
function showMessage() {
  // t() 的第一个参数是翻译键,第二个是可选参数
  alert(t('login.success'))
}
</script>

四、第三步:语言切换功能

我们需要一个地方让用户切换语言,通常放在顶部导航或设置页。

4.1 切换语言的逻辑

<!-- 比如放在 App.vue 里 -->
<template>
  <div>
    <!-- 两个按钮切换语言 -->
    <button @click="switchLanguage('zh')">中文</button>
    <button @click="switchLanguage('en')">English</button>
    <!-- 页面内容 -->
    <router-view />
  </div>
</template>
<script setup>
import { useI18n } from 'vue-i18n'
const { locale } = useI18n()
function switchLanguage(lang) {
  // 直接修改 locale 的值,整个应用的翻译会自动更新
  locale.value = lang
  // 保存到本地,下次打开还是这个语言
  localStorage.setItem('lang', lang)
}
</script>

解释:

  • locale 是一个 ref,修改它之后,所有用到 $t() 的地方都会立即刷新。
  • 把选择存到 localStorage,这样刷新页面后语言不会丢。

4.2 初始化时读取缓存

在 src/locales/index.js 里,创建 i18n 实例时先从本地缓存读语言设置。

// src/locales/index.js(改进版)
import { createI18n } from 'vue-i18n'
import zh from './zh.js'
import en from './en.js'
// 从 localStorage 里取上次设置的语言,没有就默认中文
const savedLang = localStorage.getItem('lang') || 'zh'
const i18n = createI18n({
  legacy: false,
  locale: savedLang,  // 用缓存的语言
  fallbackLocale: 'zh',
  messages: { zh, en },
})
export default i18n

五、第四步:Element Plus 的国际化

如果你用了 Element Plus 做 UI,它的组件内部也有文字(比如分页器的“共 xx 条”、日历的月份等)。这些也需要跟着语言切换。

5.1 安装 Element Plus 的中英文包

Element Plus 自带多语言支持,我们只需要引入对应的语言包,并在切换语言时同步更新。

npm install element-plus

5.2 在main.js中配置

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import i18n from './locales'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
// 引入 Element Plus 的中文和英文包
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import en from 'element-plus/dist/locale/en.mjs'
const app = createApp(App)
// 先注册 i18n
app.use(i18n)
// 注册 Element Plus,先用中文
app.use(ElementPlus, { locale: zhCn })
app.mount('#app')

5.3 切换语言时同步更新 Element Plus 的语言

在刚才的 switchLanguage 里加一行:

<script setup>
import { useI18n } from 'vue-i18n'
import { use } from 'element-plus'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import en from 'element-plus/dist/locale/en.mjs'
const { locale } = useI18n()
function switchLanguage(lang) {
  locale.value = lang
  localStorage.setItem('lang', lang)
  // 同步更新 Element Plus 的语言
  // use() 是 Element Plus 提供的全局方法,可以切换配置
  const { locale: elLocale } = use()
  elLocale.value = lang === 'zh' ? zhCn : en
}
</script>

解释:

  • elLocale.value 是 Element Plus 内部维护的当前语言,改它就能让所有 Element 组件跟着变。

六、实战案例:一个带语言切换的登录页

把上面的知识揉在一起,做一个完整的登录页,支持中英文切换。

<!-- views/Login.vue -->
<template>
  <div class="login-page">
    <!-- 语言切换按钮 -->
    <div class="lang-switch">
      <button @click="switchLanguage('zh')">中文</button>
      <button @click="switchLanguage('en')">English</button>
    </div>
    <!-- 登录表单 -->
    <div class="login-form">
      <h2>{{ $t('login.title') }}</h2>
      <!-- 用户名 -->
      <el-input
        v-model="form.username"
        :placeholder="$t('login.usernamePlaceholder')"
      >
        <template #prefix>
          <span>{{ $t('login.username') }}</span>
        </template>
      </el-input>
      <!-- 密码 -->
      <el-input
        v-model="form.password"
        type="password"
        :placeholder="$t('login.passwordPlaceholder')"
      >
        <template #prefix>
          <span>{{ $t('login.password') }}</span>
        </template>
      </el-input>
      <!-- 记住密码 -->
      <el-checkbox v-model="form.remember">
        {{ $t('login.remember') }}
      </el-checkbox>
      <!-- 登录按钮 -->
      <el-button type="primary" @click="handleLogin">
        {{ $t('login.submit') }}
      </el-button>
    </div>
  </div>
</template>
<script setup>
import { reactive } from 'vue'
import { useI18n } from 'vue-i18n'
import { ElMessage } from 'element-plus'
const { t, locale } = useI18n()
const form = reactive({
  username: '',
  password: '',
  remember: false,
})
function handleLogin() {
  // 简单模拟登录
  if (form.username && form.password) {
    ElMessage.success(t('login.success'))
  } else {
    ElMessage.error(t('login.failed'))
  }
}
function switchLanguage(lang) {
  locale.value = lang
  localStorage.setItem('lang', lang)
}
</script>
<style scoped>
.login-page {
  max-width: 400px;
  margin: 100px auto;
}
.lang-switch {
  text-align: right;
  margin-bottom: 20px;
}
.login-form {
  display: flex;
  flex-direction: column;
  gap: 15px;
}
</style>

效果: 点击顶部“中文”或“English”,整个登录页的文字、输入框提示、Element 组件上的文字、成功/失败的提示消息,全部同步切换。

七、常用技巧补充

7.1 翻译时传参数

有些文案需要动态内容,比如 "欢迎你,{name}",不同用户看到的名字不一样。

在语言包里定义:

// zh.js
export default {
  welcome: '欢迎你,{name}!',
}
// en.js
export default {
  welcome: 'Welcome, {name}!',
}

在组件里传参:

<p>{{ $t('welcome', { name: userName }) }}</p>

$t 的第二个参数是一个对象,键名对应语言包里的 {xxx} 占位符。

7.2 复数处理

不同语言对复数的规则不一样,i18n 支持复数语法,但一般项目里简单用条件判断也行,这个了解即可。

八、总结

今天我们完整地给 Vue3 项目加上了国际化,流程回顾:

步骤干什么关键代码
安装引入 vue-i18nnpm install vue-i18n@9
语言包把文案抽成 JS 文件export default { login: { title: '登录' } }
创建实例在 createI18n 里注册语言包const i18n = createI18n({ ... })
挂载app.use(i18n)main.js 里一行搞定
模板使用$t('路径'){{ $t('login.title') }}
JS 使用useI18n().tconst { t } = useI18n()
切换语言修改 locale.valuelocale.value = 'en'
UI 库同步同步 Element Plus 的 localeelLocale.value = 对应包

国际化看着大,其实核心就是把散落在各处的文字集中管理。一旦搭好这套架子,以后加新语言、改文案都很轻松。

以上就是一文详解如何在Vue3项目中实现国际化功能的详细内容,更多关于Vue3实现国际化功能的资料请关注脚本之家其它相关文章!

相关文章

  • vue实现组件之间传值功能示例

    vue实现组件之间传值功能示例

    这篇文章主要介绍了vue实现组件之间传值功能,结合实例形式分析了vue.js父子组件之间相互传值常见操作技巧,需要的朋友可以参考下
    2018-07-07
  • Vue动态样式几种常用方法总结

    Vue动态样式几种常用方法总结

    这篇文章主要给大家介绍了关于Vue动态样式几种常用方法总结的相关资料,在我们的前端界面中,很多的地方的样式都是不确定的状态,要根据其他内容的变化而变化样式的,需要的朋友可以参考下
    2023-08-08
  • 详谈Vue.js框架下main.js,App.vue,page/index.vue之间的区别

    详谈Vue.js框架下main.js,App.vue,page/index.vue之间的区别

    这篇文章主要介绍了详谈Vue.js框架下main.js,App.vue,page/index.vue之间的区别,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • Element的Message弹窗重复弹出问题解决

    Element的Message弹窗重复弹出问题解决

    本文主要介绍了Element的Message弹窗重复弹出,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • vue3 el-table 如何通过深度选择器::v-deep修改组件内部样式(默认样式)

    vue3 el-table 如何通过深度选择器::v-deep修改组件内部样式(默认样式)

    在Vue3中,通过使用深度选择器::v-deep可以有效修改element-plus中el-table组件的内部样式,这种方法允许开发者覆盖默认的样式,实现自定义的视觉效果,本文给大家介绍vue3 el-table 通过深度选择器::v-deep修改组件内部样式,感兴趣的朋友一起看看吧
    2024-10-10
  • 解决Vue @submit 提交后不刷新页面问题

    解决Vue @submit 提交后不刷新页面问题

    这篇文章主要介绍了解决Vue @submit 提交后不刷新页面问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • Vue.JS入门教程之自定义指令

    Vue.JS入门教程之自定义指令

    这篇文章主要为大家详细介绍了Vue.JS入门教程之自定义指令,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • vue-lazyload图片延迟加载插件的实例讲解

    vue-lazyload图片延迟加载插件的实例讲解

    下面小编就为大家分享一篇vue-lazyload图片延迟加载插件的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-02-02
  • Vue2 模版指令元素绑定事件执行顺序解析

    Vue2 模版指令元素绑定事件执行顺序解析

    这篇文章主要为大家介绍了Vue2 模版指令元素绑定事件执行顺序解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • Vue中常见的几种传参方式小结

    Vue中常见的几种传参方式小结

    Vue组件的使用不管是在平常工作还是在面试面试中,都是频繁出现的,下面这篇文章主要给大家介绍了关于Vue中常见的几种传参方式的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-05-05

最新评论