【unibest】uniapp 最佳多语言实践,更高的视野,降维打击!

【unibest】uniapp 最佳多语言实践,更高的视野,降维打击!

最近了解到有几个粉丝写 unibest 时有 多语言 的需求,并且是很多个语言,不只是 uniapp 官方默认支持的 5 个语言;同时粉丝觉得 uniapp 官方默认的 json 文件不能写注释,key 全部是平铺的,不能分模块等各种体验不佳,希望能改善一下。

菲鸽 最乐于助人,粉丝的需求肯定是要满足的,实现思路:

  • 使用 ts/jsonc/json5/js 的方式编写文件,使用文件监听的方式,自动生成 json 文件。
  • 支持使用 模块化 的方式编写,支持 平铺 + 非平铺 的方式编写多语言文件。

所有代码都已经放到 unibest 项目地址


我们正式开始,文章分 5 部分

  • uniapp 多语言基础:主要介绍 基本的 uniapp 多语言怎么引入和使用的
  • uniapp 多语言进阶:主要介绍 文件监听 的方式自动生成 json 文件
  • uniapp 多语言进化:主要介绍 模块化平铺 + 非平铺 的方式。
  • uniapp 多语言升化:主要介绍 使用第三方服务(比如百度翻译),自动翻译
  • uniapp 多语言气化:主要介绍 如何把上诉东西编写成一个 vite 插件就像 @uni-helper/vite-plugin-uni-pages 一样

一、uniapp 多语言基础(熟悉的同学可以跳过本节)

src/locale 里面写 en.json, zh-Hans.json 等多语言文件,如下:

tree 复制代码
./src/locale
├── en.json
├── index.ts
└── zh-Hans.json

统一在 src/locale/index.ts 中引入这些 json 文件,并使用 vue-i18ncreateI18n 函数生成 i18n 实例,最后在 src/main.tsapp.use(i18n) 即可。

diff 复制代码
// filename: src/main.ts
import { createSSRApp } from 'vue'
import App from './App.vue'
+ import i18n from './locale/index'

export function createApp() {
  const app = createSSRApp(App)
+  app.use(i18n)
  return {
    app,
  }
}

下面的 src/locale/index.ts 文件,除了实现最基础的功能之外,还实现了 translate 函数,方便在 非 vue 文件 (一般是 ts 文件)中使用多语言,这也是一个粉丝提到的一个功能。

ts 复制代码
// filename: src/locale/index.ts
import { createI18n } from 'vue-i18n'

import en from './en.json'
import zhHans from './zh-Hans.json' // 简体中文

const messages = {
  en,
  'zh-Hans': zhHans, // key 不能乱写,查看截图 screenshots/i18n.png
}

const i18n = createI18n({
  locale: uni.getLocale(), // 获取已设置的语言,fallback 语言需要再 manifest.config.ts 中设置
  messages,
})

console.log(uni.getLocale())
console.log(i18n.global.locale)

/**
 * 非 vue 文件使用这个方法
 * @param { string } localeKey 多语言的key,eg: "app.name"
 */
export const translate = (localeKey: string) => {
  if (!localeKey) {
    console.error(`[i18n] Function translate(), localeKey param is required`)
    return ''
  }
  const locale = uni.getLocale()
  console.log('locale:', locale)

  const message = messages[locale]
  if (Object.keys(message).includes(localeKey)) {
    return message[localeKey]
  }
  return localeKey
}
export default i18n

vue 文件怎么写呢?$t 函数包裹即可,支持传参数

html 复制代码
<view class="m-4">{{ $t('weight', { heavy: 100 }) }}</view>

对应的 json 文件如下,以 en.json 为例:

json 复制代码
{
  "weight": "{heavy} KG",
}

怎么切换多语言呢?通常为写一个 radio,在里面的 @change 事件中编写:

html 复制代码
<view class="uni-list">
  <radio-group @change="radioChange" class="radio-group">
    <label class="uni-list-cell uni-list-cell-pd" v-for="item in languages" :key="item.value">
      <view>
        <radio :value="item.value" :checked="item.value === current" />
      </view>
      <view>{{ item.name }}</view>
    </label>
  </radio-group>
</view>

对应的 script setup 如下:

ts 复制代码
import i18n from '@/locale/index'
const current = ref(uni.getLocale())
const languages = [
  {
    value: 'zh-Hans',
    name: '中文',
    checked: 'true',
  },
  {
    value: 'en',
    name: '英文',
  },
]
const radioChange = (evt) => {
  // console.log(evt)
  current.value = evt.detail.value
  // 下面2句缺一不可!!!
  uni.setLocale(evt.detail.value)
  i18n.global.locale = evt.detail.value
}

最后,多语言标题怎么办? 需要在 pages.json 中把 navigationBarTitleText 写成 %xxx% 这种形式,eg:

json 复制代码
{
  "path": "pages/demo/i18n",
  "type": "page",
  "style": {
    "navigationBarTitleText": "%app.name%"
  }
}

注意事项:

    1. 默认支持 5 种语言,其他语言 uniapp 不认识 (不是 vue-i18n 不认识)。
    • 英语 en
    • 中文简体 zh-Hans
    • 繁体 zh-Hant
    • 法语 fr
    • 西班牙语 es

    如果是其他语言,vue 文件里面的是认识的,但是 uniapp 的标题 navigationBarTitleText 就不会自动翻译了,这个时候需要使用 uni.setNavigationBarTitle 手动处理,并且需要监听多语言的切换(很重要!)。

    1. 多语言文件夹为 src/locale ,不能改为 locales 或其他。
    1. json 文件的 key 是平铺的,不能写成对象的形式。

总结

本文一步一步完成了 uniapp 多语言的最佳实践,步骤如下:

  • uniapp 多语言基础:主要介绍 基本的 uniapp 多语言怎么引入和使用的
  • uniapp 多语言进阶:主要介绍 文件监听 的方式自动生成 json 文件
  • uniapp 多语言进化:主要介绍 模块化平铺 + 非平铺 的方式。
  • uniapp 多语言升化:主要介绍 使用第三方服务(比如百度翻译),自动翻译
  • uniapp 多语言气化:主要介绍 如何把上诉东西编写成一个 vite 插件就像 @uni-helper/vite-plugin-uni-pages 一样

好文推荐

🔥2024 年最好用的 uniapp 开发模板,近一个月 star 数飙升!🔥 - 点赞数:304, 收藏数:650 (前端收藏榜榜第八)

相关推荐
素**颜11 分钟前
uniapp 基于xgplayer(西瓜视频) + renderjs开发,实现APP视频播放
javascript·uni-app·音视频
顽疲36 分钟前
从零用java实现 小红书 springboot vue uniapp (6)用户登录鉴权及发布笔记
java·vue.js·spring boot·uni-app
竣子好逑4 小时前
uniapp 微信小程序 数据空白展示组件
微信小程序·小程序·uni-app
孙 悟 空1 天前
uni-app:监听页面返回,禁用返回操作
前端·javascript·uni-app
mosen8681 天前
uniapp中uni.scss如何引入页面内或生效
前端·uni-app·scss
lyz2468591 天前
uniapp popup弹窗组件的自定义使用方法
uni-app
沙尘暴炒饭1 天前
uniapp 前端解决精度丢失的问题 (后端返回分布式id)
前端·uni-app
牛牛科技1 天前
生产管理系统PHP+Uniapp源码
uni-app
Smile_ping1 天前
uniapp——APP读取bin文件,解析文件的数据内容(一)
uni-app·uniapp 读取文件·app端读取bin文件
CDERP-plus1 天前
uniapp 3分钟集成轮播广告图
uni-app·erp·erp移动端