vue如何实现国际化,它来了!

Vue 3 接入 vue-i18n 完整教程(零基础版)

手把手教程,面向完全没接触过国际化 的初学者。

每一步都会解释"为什么这么做",跟着做即可把国际化接入任意 Vue 3 项目。


一、什么是国际化(i18n)?

i18n = internationalization(international 有 18 个字母,首尾 i、n 加上 18 就写成 i18n)。

简单说:同一套代码,根据不同语言显示不同文字。

语言 显示
中文 首页
英文 Home
日语 ホーム

vue-i18n 是 Vue 官方推荐的国际化插件,它帮你做三件事:

  1. 把页面上所有文字集中存到"语言包"里,不在代码里写死。
  2. 用一个 key(钥匙)来取文字,而不是直接写文字。
  3. 切换语言时,页面所有文字自动跟着变

二、从零接入的 6 个步骤

第 1 步:安装依赖

bash 复制代码
npm install vue-i18n
# 或使用 pnpm
pnpm add vue-i18n
# 或使用 yarn
yarn add vue-i18n

装完打开 package.json,在 dependencies 里能看到 "vue-i18n": "^11.4.8"


第 2 步:创建语言包文件

语言包就是一个普通对象,里面存了"中文"和"英文"各怎么说。

先建目录 src/i18n/locales/,然后新建 src/i18n/locales/zh-CN.ts

ts 复制代码
export default {
  nav: {
    home: '首页',
    about: '关于',
  },
  about: {
    title: '关于页面',
  },
}

再新建 src/i18n/locales/en-US.ts

ts 复制代码
export default {
  nav: {
    home: 'Home',
    about: 'About',
  },
  about: {
    title: 'About Page',
  },
}

关键理解:

  • 两个文件的结构一模一样 ,只是值不同。key(nav.home)是"钥匙",值是"不同语言下的说法"。
  • 代码里永远只写 $t('nav.home') 这个 key,绝不写死文字。这样以后改文案不用翻代码。

第 3 步:创建 i18n 实例

新建 src/i18n/index.ts,这是整个国际化的"心脏":

ts 复制代码
import { createI18n } from 'vue-i18n'
import zhCN from './locales/zh-CN'
import enUS from './locales/en-US'

const i18n = createI18n({
  legacy: false,          // 开启 Composition API 模式(Vue3 推荐)
  locale: 'zh-CN',        // 默认语言
  fallbackLocale: 'en-US', // 找不到 key 时兜底用英文,避免白屏
  messages: {
    'zh-CN': zhCN,
    'en-US': enUS,
  },
})

export default i18n

逐个解释配置项:

  • legacy: false:Vue3 里必须关掉旧模式,才能在 <script setup> 里用 useI18n()
  • locale:当前语言,切换语言就是改它。
  • fallbackLocale:兜底语言。比如中文包漏了一个 key,就自动显示英文,页面不会空白。
  • messages:把所有语言包都注册进来,一个 key 对应一个文件。

第 4 步:注册到应用入口

打开 src/main.ts,把 i18n 装进 Vue 应用里:

ts 复制代码
import { createApp } from 'vue'
import App from './App.vue'
import i18n from './i18n'        // ① 导入

const app = createApp(App)

app.use(i18n)                    // ② 注册,模板里才能用 $t()
app.mount('#app')

不注册的话,模板里 $t() 是不可用的。app.use() 就是告诉 Vue:"我有个插件,请全局启用它"。


第 5 步:在组件里用 $t() 替换写死的文字

模板里使用(最常用),以导航链接为例:

vue 复制代码
<!-- 之前(写死) -->
<RouterLink to="/">Home</RouterLink>

<!-- 之后(国际化) -->
<RouterLink to="/">{{ $t('nav.home') }}</RouterLink>

脚本里使用,比如要在 JS 逻辑里拿翻译:

ts 复制代码
import { useI18n } from 'vue-i18n'

const { t, locale } = useI18n()
const title = t('nav.home')   // 当前语言是中文时返回 '首页'

带参数的翻译 (文字里有动态内容),在语言包里用 {xxx} 占位:

ts 复制代码
// 语言包里
hello: { desc: '你已成功使用 {tech1} + {tech2} 创建了一个项目。' }

// 模板里传入具体值
{{ $t('hello.desc', { tech1: 'Vite', tech2: 'Vue 3' }) }}
// 输出:你已成功使用 Vite + Vue 3 创建了一个项目。

规律: 看到页面上有写死的文字,就照抄这个三步走------

① 在语言包里加一个 key;② 在模板里替换成 $t('key');③ 确保每个语言包都有这个 key。


第 6 步:做语言切换

语言切换的本质 = 改变 locale 的值,改完页面自动重渲染。

可以封装一个切换函数,同时做三件事(更新语言 + 记住选择 + 同步给浏览器):

ts 复制代码
export function setLocale(locale: string) {
  i18n.global.locale.value = locale   // 1. 真正切换语言
  localStorage.setItem('app-locale', locale)  // 2. 记住用户选择
  document.documentElement.lang = locale      // 3. 同步给浏览器
}
  • 下拉框里有什么语言,由 SUPPORT_LOCALES 数组决定。

  • 想支持"用户刷新后语言不变",就在创建 i18n 时读取 localStorage

    ts 复制代码
    const saved = localStorage.getItem('app-locale')

三、自己动手试试

启动开发服务器后,你会看到:

  1. 页面右上角有语言下拉框,切换中英文,整个页面文字立刻变化
  2. 刷新页面,语言保持不变(被 localStorage 记住了)。
  3. 无痕窗口打开,若代码里加了浏览器语言检测,会自动跟随。

练习任务:

  • 在某一个页面上新加一句话,并完成中英文两个语言包的 key。
  • 把页面里剩下的英文段落全部抽到语言包。

四、新手常犯的错误

错误 正确做法
只改了一个语言包,另一个忘了 → 另一个语言的用户看到空白 两个语言包同时加,key 结构保持一致
代码里写死 '欢迎' + name 拼接 用插值 $t('welcome', { name })
一个 key 只在一个语言包里有 所有语言包必须有相同 key,靠 fallbackLocale 兜底是最后手段
key 命名随意,比如 'hello''page1' 按页面/模块组织:nav.homeabout.title
忘了在 main.tsapp.use(i18n) 模板 $t() 会报错不可用
把整段含 HTML 链接的文字塞进语言包 链接文字单独抽 key,模板里用 <a> 标签包住 $t()

五、遇到报错怎么办

  • 模板里 $t is not defined :说明没注册,检查 main.tsapp.use(i18n)
  • 页面出现 key 原文(如 nav.home:说明这个 key 在当前语言包里不存在,检查拼写或补上翻译。
  • 切换没反应 :确认用的是 locale.value(ref 取值要 .value),不是直接赋值。
  • 类型报错 :运行类型检查命令(如 npm run type-check),看具体哪个文件的哪个 key 对不上。

记住一句话

代码里不写死任何文字,全部通过 key 从语言包取。

改文案 = 改语言包;加语言 = 加一个语言包文件。这就是国际化的全部精髓。

相关推荐
朝阳391 小时前
react19【实战】配置化路由登录鉴权完整方案
前端·javascript·react.js
其美杰布-富贵-李1 小时前
Vue Router 实战教程
前端·javascript·vue.js
NutShell Wang1 小时前
拆解 GitHub gh-stack:堆叠 PR 工作流的设计取舍与工程实现
前端·git·开源·github·代码复审·开发者工具·vibe coding
名字还没想好☜2 小时前
React 用 IntersectionObserver 实现图片懒加载与无限滚动:封装一个 useInView Hook
前端·javascript·vue.js·react.js·react
带娃的IT创业者2 小时前
Puppeteer 深度解析:超越自动化测试的现代 Web 交互范式
前端·交互·puppeteer·可观测性·浏览器自动化·无头浏览器·web工程化
程序员爱钓鱼2 小时前
Rust 所有权 Ownership 详解:理解内存安全的核心机制
前端·后端·rust
Mh10 小时前
别再只会 `find` 了:Map 在前端业务里的真实用法
前端·javascript
陈随易11 小时前
FFmpeg 9.0 发布,代号 Lei,音视频处理再升级
前端·后端·程序员
爱丶狸11 小时前
Grafana_Zabbix_ImageRenderer_部署与前端操作手册
linux·前端·zabbix·grafana·kylin