【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-i18n
的 createI18n
函数生成 i18n
实例,最后在 src/main.ts
中 app.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%"
}
}
注意事项:
-
- 默认支持
5
种语言,其他语言uniapp
不认识 (不是vue-i18n
不认识)。
- 英语 en
- 中文简体 zh-Hans
- 繁体 zh-Hant
- 法语 fr
- 西班牙语 es
如果是其他语言,
vue
文件里面的是认识的,但是uniapp
的标题navigationBarTitleText
就不会自动翻译了,这个时候需要使用uni.setNavigationBarTitle
手动处理,并且需要监听多语言的切换(很重要!)。 - 默认支持
-
- 多语言文件夹为
src/locale
,不能改为locales
或其他。
- 多语言文件夹为
-
json
文件的key
是平铺的,不能写成对象的形式。
总结
本文一步一步完成了 uniapp
多语言的最佳实践,步骤如下:
- uniapp 多语言基础:主要介绍
基本的
uniapp
多语言怎么引入和使用的 - uniapp 多语言进阶:主要介绍
文件监听
的方式自动生成json
文件 - uniapp 多语言进化:主要介绍
模块化
和平铺 + 非平铺
的方式。 - uniapp 多语言升化:主要介绍
使用第三方服务(比如百度翻译),自动翻译
- uniapp 多语言气化:主要介绍 如何把上诉东西编写成一个 vite 插件就像
@uni-helper/vite-plugin-uni-pages
一样
好文推荐
🔥2024 年最好用的 uniapp 开发模板,近一个月 star 数飙升!🔥 - 点赞数:304, 收藏数:650 (前端收藏榜榜第八)