Vue3+Uniapp 环境多语言实现方案
本质上是通过人为翻译后将内容存储在 JSON 文件中,当用户选择语言时调用对应文件实现多语言切换。
一、基础设计
项目结构
md
md
📂 项目结构
├── src
│ ├── locales # 多语言资源目录
│ │ ├── en-US.json # 英语
│ │ ├── zh-CN.json # 简体中文
│ │ └── index.js # 语言加载器
│ ├── composables
│ │ └── useI18n.js # 国际化组合函数
│ ├── pages
│ │ └── [...].vue # 页面组件
│ ├── App.vue # 应用入口
│ └── main.js # 主入口文件
多语言实现的核心思路是:将页面中所有需要展示的文字内容,通过对应语言的键值对进行替换。默认情况下,根据用户系统自带语言加载对应的语言包;当用户手动选择其他语言时,切换到相应的语言包,从而实现页面文字的翻译效果。
例如,在页面中通过调用翻译函数,使用统一的键来获取不同语言的对应值,如下所示的代码逻辑:



二、代码讲解
1. 准备语言资源
将需要翻译的内容以键值对形式存储在对应的语言文件中,键名可自定义,只要便于理解和使用即可。
- zh-CN.json(简体中文)
json
json
{
"title": "这是中文",
"hello": "欢迎"
}
- en-US.json(英语)
json
json
{
"title": "this is english",
"hello": "welcome"
}
这里的键(key)相当于一个统一的标识,值(value)是对应语言的翻译内容。不同语言文件中相同的键,对应不同的翻译值,从而实现通过同一个键在不同语言环境下获取不同文本的效果。
2. 语言加载器(locales/index.js)
js
js
const messages = {
'zh-CN': require('./zh-CN.json'),
'en-US': require('./en-US.json')
}
// 获取系统语言
export const getSystemLanguage = () => {
const systemLang = uni.getSystemInfoSync().language
return Object.keys(messages).includes(systemLang)
? systemLang
: 'en-US'
}
// 获取当前语言包
export const getMessages = (lang) => messages[lang] || messages['en-US']
- 功能说明:该文件用于加载语言资源,实现根据系统语言或指定语言获取对应的语言包。
- getSystemLanguage 函数 :通过
uni.getSystemInfoSync().language
获取用户系统语言,若系统语言在我们提供的语言包中存在,则返回该语言;否则,默认返回英语('en-US')。 - getMessages 函数:根据传入的语言参数,返回对应的语言包;若该语言包不存在,则默认返回英语语言包。
3. 国际化组合函数(composables/useI18n.js)
js
js
import { ref, computed } from 'vue'
import { getMessages, getSystemLanguage } from '@/locales'
// 创建响应式语言状态
const currentLang = ref(uni.getStorageSync('user_lang') || getSystemLanguage())
export default function useI18n() {
// 获取翻译文本
const t = (key, params = {}) => {
const keys = key.split('.')
let message = getMessages(currentLang.value)
for (const k of keys) {
if (!message[k]) return key
message = message[k]
}
// 处理带参数的文本
return Object.entries(params).reduce((msg, [k, v]) =>
msg.replace(new RegExp(`{${k}}`, 'g'), v),
message
)
}
// 切换语言
const setLanguage = (lang) => {
currentLang.value = lang
uni.setStorageSync('user_lang', lang)
// 刷新页面(根据需求选择)
// uni.reLaunch({ url: '/' })
}
// 当前语言响应式引用
const language = computed(() => currentLang.value)
return { t, setLanguage, language }
}
在讲解该函数前,先简单介绍ref
和computed
:
-
ref:Vue3 的核心 API,用于将数据包装成响应式数据。
- 特点:包装后的数据需通过
.value
属性访问(在 JavaScript 中),在模板中会自动解包,无需使用.value
。 - 适用场景:基本类型的响应式数据、需要直接访问和修改的数据、需要传递给函数并保持响应性的数据。
- 特点:包装后的数据需通过
-
computed:用于创建基于其他响应式数据计算而来的值,会自动缓存计算结果,只有当依赖项变化时才会重新计算。
函数详解
-
currentLang :通过
ref
创建响应式的当前语言状态。优先从本地存储(uni.getStorageSync('user_lang')
)中获取用户之前选择的语言;若不存在,则通过getSystemLanguage
获取系统语言。 -
t 函数(核心翻译函数):根据传入的键(key)和参数(params),从当前语言包中获取对应的翻译文本,并处理带参数的文本。
const keys = key.split('.')
:将传入的键按.
分割为数组,用于处理嵌套结构的语言包。例如,对于键common.title
,分割后得到['common', 'title']
。let message = getMessages(currentLang.value)
:根据当前语言获取对应的语言包。for (const k of keys)
:遍历分割后的键数组,从语言包中逐层获取对应的翻译文本。若某个键不存在,则返回该键本身。- 处理带参数的文本:通过
Object.entries(params).reduce
方法,将文本中{参数名}
的占位符替换为实际的参数值。例如,对于文本"欢迎{name}!"
和参数{name: '张三'}
,处理后得到"欢迎张三!"
。
-
setLanguage 函数 :用于切换语言。将传入的语言设置为当前语言(
currentLang.value = lang
),并将该语言存储到本地(uni.setStorageSync('user_lang', lang)
),以便下次打开应用时使用。 -
language :通过
computed
创建当前语言的响应式引用,便于在组件中获取当前语言。
4. App.vue 中的使用逻辑
在 App.vue 的 JavaScript 部分,通常会进行语言的初始化判断:首次启动应用时,若本地存储中没有user_lang
(即用户未选择过语言),则跳转至语言选择界面;若存在,则直接使用该语言设置当前语言。
这样,当应用重新启动时,会从本地存储中读取用户之前选择的语言,保证语言设置的连贯性。