uni-app工程化实战:基于vue-i18n和i18n-ally的国际化方案 (上)

前言

今天,我们将深入探讨uni-app项目的国际化实现,据统计,超过70%的全球用户更倾向于使用母语浏览内容,而支持多语言的应用在国际市场的转化率平均提升40%,换句人话来说就是看都看不懂我还买个锤子呢?所以一个产品想要出海,从全球市场获取收益,赚洋人的刀乐,完善的国际化方案是不可或缺的。

本教程将系统化地「拆解」uni-app项目中的国际化实现流程,从环境搭建到实战应用,手把手教你使用vue-i18n结合vscode插件i18n-allyWotUI构建灵活高效的多语言支持系统,包含了各类平台(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>
相关推荐
喵个咪1 小时前
基于 Flutter 的 Headless CMS 全平台前端架构:技术解析与二次开发导引
前端·flutter·cms
vim怎么退出2 小时前
Dive into React——Diff 算法
前端·react.js·源码阅读
半个落月2 小时前
面试必问的 JS 原型链,我用 16 个示例给你彻底讲明白
javascript
拾年2752 小时前
别调 BERT 了:我用 Prompt 做了套 NLP 系统,20 分钟搞定
前端·人工智能
丷丩2 小时前
12. 渲染:MapLibre GL JS 集成与多源瓦片联动
javascript·矢量瓦片·maplibre gl js·地图服务器
半个落月2 小时前
别再死记变量提升了——从 V8 编译过程真正理解 JS 执行机制
前端
橘子星2 小时前
别再懵圈!JS 执行机制的 “千层套路” 全揭秘
前端·javascript
GuWenyue2 小时前
LeetCode 76 最小覆盖子串|JS 滑动窗口标准解法
前端·算法·面试
YHHLAI2 小时前
前端 HTTP 请求 & LLM 接口开发
前端·网络协议·http