前言
今天,我们将深入探讨uni-app项目的国际化实现,据统计,超过70%的全球用户更倾向于使用母语浏览内容,而支持多语言的应用在国际市场的转化率平均提升40%,换句人话来说就是看都看不懂我还买个锤子呢?所以一个产品想要出海,从全球市场获取收益,赚洋人的刀乐,完善的国际化方案是不可或缺的。
本教程将系统化地「拆解」uni-app项目中的国际化实现流程,从环境搭建到实战应用,手把手教你使用vue-i18n结合vscode插件i18n-ally与WotUI构建灵活高效的多语言支持系统,包含了各类平台(H5、小程序、App)的适配要点与优化策略。准备好了吗?Let's go! 不对,应该是「出发吧」...哦等等,这不就是国际化的意义所在吗?😉
注意:本项目是基于Vue3和WotUI的uni-app cli框架开发的,如果你使用的是Vue2,请参考uni-app文档进行相应调整。
1. 安装和配置vue-i18n
1.1 安装依赖
首先,我们需要安装vue-i18n:
# 使用npm
npm install vue-i18n@9.1.9
# 或者使用yarn
yarn add vue-i18n@9.1.9
# 或者使用pnpm
pnpm add vue-i18n@9.1.9
注意:根据uni-app官方文档建议,Vue3项目需要安装vue-i18n的固定版本9.1.9,和uni-app内部使用的vue-i18n保持一致。
1.2 创建i18n实例
在项目中创建一个专门的目录来存放国际化相关的文件,例如src/locale:
// src/locale/index.ts
import { createI18n } from "vue-i18n"
import zhCN from "./zh-CN.json"
import enUS from "./en-US.json"
import { Locale } from "@wot-ui/ui"
import WotEnUS from "@wot-ui/ui/locale/lang/en-US"
Locale.add({ "en-US": WotEnUS })
const messages = {
"zh-CN": {
...zhCN
},
"en-US": {
...enUS
}
}
// 创建i18n实例
const i18n = createI18n({
locale: uni.getStorageSync("currentLang") || "zh-CN", // 默认语言
fallbackLocale: "zh-CN", // 回退语言
messages, // 语言包
legacy: false, // 启用Composition API模式
globalInjection: true // 全局注入 $t 等方法到模板
})
// 同步组件库语言
Locale.use(i18n.global.locale.value)
uni.setLocale(i18n.global.locale.value)
export default i18n
1.3 在main.js中注册i18n
// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import i18n from './locale'
const app = createApp(App)
app.use(i18n)
app.mount('#app')
2. 语言文件的组织结构
2.1 基本结构
语言文件通常以JSON格式存储,每种语言一个文件:
src/locale/
├── index.ts # i18n配置和实例
├── zh-CN.json # 中文语言包
└── en-US.json # 英文语言包
2.2 语言文件内容
语言文件是键值对的集合,键是唯一标识符,值是对应语言的文本:
// zh-CN.json
{
"hello": "你好",
"welcome": "欢迎使用",
"button": "按钮"
}
// en-US.json
{
"hello": "Hello",
"welcome": "Welcome to use",
"button": "Button"
}
2.3 嵌套结构
对于复杂应用,可以使用嵌套结构组织语言文件:
// zh-CN.json
{
"common": {
"confirm": "确认",
"cancel": "取消"
},
"home": {
"title": "首页",
"welcome": "欢迎回来"
}
}
3. 使用useI18nSync钩子实现多语言切换
在项目中,我们实现了一个useI18nSync钩子来同步应用和组件库的语言设置:
// src/hooks/useI18nSync.ts
import { computed, onBeforeMount } from "vue"
import { Locale } from "@wot-ui/ui"
import i18n from "../locale"
const SUPPORTED_LOCALES = ["zh-CN", "en-US"]
function setLocale(locale, syncComponentLib = true) {
if (!SUPPORTED_LOCALES.includes(locale)) {
console.warn(`不支持的语言: ${locale},将使用默认语言 zh-CN`)
locale = "zh-CN"
}
uni.setLocale(locale)
i18n.global.locale.value = locale
uni.setStorageSync("currentLang", locale)
if (syncComponentLib) {
Locale.use(locale)
}
return locale
}
function initLocale(defaultLocale, syncComponentLib) {
const storedLocale = uni.getStorageSync("currentLang") || defaultLocale
setLocale(storedLocale, syncComponentLib)
}
/**
* 国际化同步hook
* @param {Object} options 配置选项
* @param {boolean} options.syncComponentLib - 是否同步组件库语言
* @param {string} options.defaultLocale - 默认语言
* @returns {Object} 国际化相关方法和状态
*/
export function useI18nSync(options) {
const { syncComponentLib = true, defaultLocale = "zh-CN" } = options || {}
const currentLang = computed(() => i18n.global.locale.value)
onBeforeMount(() => {
initLocale(defaultLocale, syncComponentLib)
})
return {
currentLang,
setLocale: locale => setLocale(locale, syncComponentLib),
supportedLocales: SUPPORTED_LOCALES
}
}
3.1 在App.vue中初始化语言
<script setup lang="ts">
import { useI18nSync } from './hooks/useI18nSync'
// 初始化国际化设置
const { setLocale } = useI18nSync()
onLaunch(options => {
console.log("App.vue onLaunch", options)
const storedLocale = uni.getStorageSync("currentLang") || "zh-CN"
setLocale(storedLocale)
})
</script>
3.2 实现语言切换功能
<template>
<view class="language-switcher">
<view class="current-lang">{{ $t('dangQianYuYan') }}: {{ currentLang }}</view>
<wd-button @click="switchLanguage('zh-CN')">中文</wd-button>
<wd-button @click="switchLanguage('en-US')">English</wd-button>
</view>
</template>
<script setup lang="ts">
import { useI18nSync } from '../hooks/useI18nSync'
const { currentLang, setLocale } = useI18nSync()
function switchLanguage(locale: string) {
setLocale(locale)
}
</script>
4. 在组件中使用国际化文本
4.1 使用Composition API
在Vue3的Composition API中使用i18n:
<template>
<view class="page">
<view class="title">{{ t('hello') }}</view>
<view class="content">{{ t('welcome') }}</view>
<wd-button>{{ t('button') }}</wd-button>
</view>
</template>
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
</script>
4.2 使用模板语法
直接在模板中使用$t函数:
<template>
<view class="page">
<view class="title">{{ $t('hello') }}</view>
<view class="content">{{ $t('welcome') }}</view>
<wd-button>{{ $t('button') }}</wd-button>
</view>
</template>
4.3 动态计算属性
使用computed使内容响应语言变化:
<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
// 使用computed使list响应语言变化
const list = computed(() => [
{
id: 'widget',
name: t('ji-chu'),
pages: [
{
id: 'button',
name: t('button-an-niu')
},
// 其他项...
]
}
])
</script>