Vue3+Uniapp 环境多语言实现方案

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 }
}

在讲解该函数前,先简单介绍refcomputed

  • ref:Vue3 的核心 API,用于将数据包装成响应式数据。

    • 特点:包装后的数据需通过.value属性访问(在 JavaScript 中),在模板中会自动解包,无需使用.value
    • 适用场景:基本类型的响应式数据、需要直接访问和修改的数据、需要传递给函数并保持响应性的数据。
  • computed:用于创建基于其他响应式数据计算而来的值,会自动缓存计算结果,只有当依赖项变化时才会重新计算。

函数详解
  • currentLang :通过ref创建响应式的当前语言状态。优先从本地存储(uni.getStorageSync('user_lang'))中获取用户之前选择的语言;若不存在,则通过getSystemLanguage获取系统语言。

  • t 函数(核心翻译函数):根据传入的键(key)和参数(params),从当前语言包中获取对应的翻译文本,并处理带参数的文本。

    1. const keys = key.split('.'):将传入的键按.分割为数组,用于处理嵌套结构的语言包。例如,对于键common.title,分割后得到['common', 'title']
    2. let message = getMessages(currentLang.value):根据当前语言获取对应的语言包。
    3. for (const k of keys):遍历分割后的键数组,从语言包中逐层获取对应的翻译文本。若某个键不存在,则返回该键本身。
    4. 处理带参数的文本:通过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(即用户未选择过语言),则跳转至语言选择界面;若存在,则直接使用该语言设置当前语言。

这样,当应用重新启动时,会从本地存储中读取用户之前选择的语言,保证语言设置的连贯性。

相关推荐
wycode3 小时前
Vue2源码笔记(1)编译时-模板代码如何生效之生成AST树
前端·vue.js
狂炫一碗大米饭5 小时前
vue中的继承和组合 ✏️ ✏️ ✏️
vue.js
无业哥6 小时前
Vue&ElementPlus 按需导入
vue.js
掘金017 小时前
震惊!Vue3 竟能这样写?React 开发者狂喜的「Vue-React 缝合怪」封装指南
javascript·vue.js·react.js
徐小夕8 小时前
花3个月时间,写了一款协同文档编辑器
前端·vue.js·算法
ZsTs1198 小时前
一篇通关:从 MVVM 到渲染优化,Vue 基础核心 5 大模块全解析
前端·vue.js·面试
掘金018 小时前
Vue.js 中 PDF 渲染问题的排查与优化:从部分渲染失败到稳定加载
前端·javascript·vue.js
苹果醋39 小时前
从零搭建React框架--第一章:create-react-app、antd、less
运维·vue.js·spring boot·nginx·课程设计
lichenyang4539 小时前
从0开始的中后台管理系统-5(userList页面功能实现)
前端·javascript·vue.js