参考:Vue I18n、uniapp与vue-i18n实现国际化多语言、uni-app 如何语言国际化/多语言处理
1. 一般实现
1.1 main.js
import Vue from 'vue'
import App from './App'
import i18n from './commons/i18n.js'
import en from './commons/language/en_US.js'
import zh from './commons/language/zh_CN.js'
i18n.registerLocale({en,zh})
Vue.config.productionTip = false
Vue.prototype._i18n = i18n
App.mpType = 'app'
const app = new Vue({
i18n,
...App
})
app.$mount()
备注
:main.js文件:定义全局函数和变量
(1) i18n.js
module.exports = {
locale: 'zh', // 默认选择的语言
locales: {},
registerLocale (locales) {
this.locales = locales
},
setLocale (code) {
this.locale = code
uni.setStorageSync("languageKey",code)
},
getLanguage(){
//return this.locales[this.locale];
this.locale = uni.getStorageSync("languageKey") || this.locale
return this.locales[this.locale];
},
/**
* 返回带(或不带)参数的类型的翻译结果
* @param {string} key, /util/language/en.js 中的键名,如 "curslide"
* @param {object} data, 传入的参数,如 {num: 123}
* @returns {string}
*
* @desc 如:"activeno": "当前学生{activeno}位",
* activeno 为 key,可以输入data {activeno: 15}
* 返回:"当前学生15位"
*/
_ (key, data) {
let locale = this.locale
let locales = this.locales
if (locale && locales[locale] && locales[locale][key]) {
key = locales[locale][key]
}
return key
},
/**
* 返回二选一类型的翻译结果
* @param {string} key, /util/language/en.js 中的键名,如 "curslide"
* @param {object} data, 传入的参数,如 {first: true} 选择前面的
* @returns {string}
*
* @desc 如:"sendprob": "Send | Check",
* sendprob 为 key,可以输入data {first: true}
* 返回:"Send"
*/
_b (key, data) {
let locale = this.locale
let locales = this.locales
let hasKey = locale && locales[locale] && locales[locale][key]
if (hasKey) {
key = locales[locale][key]
let res = key.split('|')[data.first ? 0 : 1].trim()
return res
}
throw new Error(`语言处理错误${key}`)
}
}
(2) zh_CN.js
module.exports = {
//通用
"currency": {
'home':'主页',
"machine":"机器",
"statistic":"统计",
"mine": "我的",
"submit":"提交"
},
//主页
"home": {
"keyword": "输入关键字",
"search": "搜索"
},
//我的
"mine":{
"langSelect": "语言选择",
"signOut": "退出",
"confirm": "确定",
"cancel": "取消"
}
}
(3) en_US.js
module.exports = {
//通用
"currency":{
'home': 'Home',
"machine":"Machine",
"statistic":"Statistic",
"mine": "Mine",
"submit":"submit"
},
//主页
"home":{
"keyword": "please input keyword",
"search": "search"
},
//我的
"mine":{
"langSelect": "Language",
"signOut": "Sign out",
"confirm": "confirm",
"cancel": "cancel"
}
}
1.2 检测系统语言并改变 locale 值
在 app.vue 的 onLaunch 中使用 uni.getSystemInfoSync()得到系统当前语言
onLaunch: function() {
console.log('App Launch');
var lan = 'zh'
try {
const res = uni.getSystemInfoSync();
lan = res.language
} catch (e) {
console.log('error='+e)
}
console.log('lan='+lan);
if(lan == 'en') {
this._i18n.setLocale('en')
}
if(lan == 'zh-Hans-CN' || lan=='zh') {
this._i18n.setLocale('zh')
}
},
1.3 国际化实现
(1) 页面两种调用方式
<template>
<view class="uni-content">
<text>{{lanObj.keyword}}</text>
<text>{{lanObj.search}}</text>
</view>
<button>{{_i18n.getLanguage().currency.submit}}</button>
</template>
<script>
export default {
data() {
return {
lanObj : {},
};
},
onLoad:function(){
this.lanObj = this._i18n.getLanguage().myhome;
}
}
</script>
<style>
</style>
(2) 底部导航和顶部导航国际化实现
- 顶部的title,用uni.setNavigationBarTitle动态设置文字
- 底部tabbar,用uni.setTabBarItem的api动态设置文字
refreshLanguage:function(){
console.log("当前语言为:"+this._i18n.locale)
this.lanObj = this._i18n.getLanguage().mine;
//顶部的title
uni.setNavigationBarTitle({
title:this._i18n.getLanguage().mine.editPerson
})
//底部tabbar
uni.setTabBarItem({
index: 0,
text: this._i18n.getLanguage().currency.home
})
uni.setTabBarItem({
index: 1,
text: this._i18n.getLanguage().currency.machine
})
uni.setTabBarItem({
index: 2,
text: this._i18n.getLanguage().currency.statistic
})
uni.setTabBarItem({
index: 3,
text: this._i18n.getLanguage().currency.mine
})
}
(3) Input 框里的placeholder
内容国际化
<input type="text" :placeholder="_i18n.getLanguage().home.search"></input>
(4) 列表数据国际化
<template>
<view class="uni-flex uni-column" style="width: 100%;height: 100%;">
<view class="flex-twice uni-flex justify-center">
<view class="cu-list grid col-3 no-border" style="width: 100%;">
<view class="cu-item" v-for="(item,index) in cuIconList" :key="index">
<view :class="['cuIcon-' + item.cuIcon,'text-' + item.color]"></view>
<text>{{item.name}}</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
lanObj : {},
cuIconList: [
{
url:'machineManage',
cuIcon: 'cardboardfill',
color: 'olive',
name: this._i18n.getLanguage().mine.machineCenter
}, {
url:'userManage',
cuIcon: 'friendfill',
color: 'blue',
name: this._i18n.getLanguage().mine.employeeCenter
}, {
url:'edgeSettings',
cuIcon: 'settingsfill',
color: 'yellow',
name: this._i18n.getLanguage().mine.edgeSetting
}, {
url:'ota',
cuIcon: 'upload',
color: 'yellow',
name: this._i18n.getLanguage().mine.firmwareUpgrade
}, {
url:'log',
cuIcon: 'form',
color: 'blue',
name: this._i18n.getLanguage().mine.logView
}, {
url:'userModify',
cuIcon: 'peoplefill',
color: 'olive',
name: this._i18n.getLanguage().mine.personalInformation
}
],
}
},
methods: {
refreshLanguage:function(){
this.lanObj = this._i18n.getLanguage().home;
this.cuIconList[0].name = this._i18n.getLanguage().mine.machineCenter;
this.cuIconList[1].name = this._i18n.getLanguage().mine.employeeCenter;
this.cuIconList[2].name = this._i18n.getLanguage().mine.edgeSetting;
this.cuIconList[3].name = this._i18n.getLanguage().mine.firmwareUpgrade;
this.cuIconList[4].name = this._i18n.getLanguage().mine.logView;
this.cuIconList[5].name = this._i18n.getLanguage().mine.personalInformation;
}
},
onLoad:function(){
},
onShow:function(){
this.refreshLanguage();
}
}
</script>
<style>
</style>
- 情形一:切换语言后国际化失败(数据列表定义为字符串数组)
<template>
<view>
<view class="bar-nav" style="margin-top: 55px;padding-bottom: 5px;">
<view class="nav-item" :class="index==TabCur? 'nav-text nav-cur':''" v-for="(item,index) in tabNav" :key="index" @tap="tabSelect" :data-id="index">
{{item}}
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
lanObj:{},
TabCur: 0,
tabNav: [this._i18n.getLanguage().device.machine,this._i18n.getLanguage().device.repeater]
}
},
methods: {
refreshLanguage:function(){
this.lanObj = this._i18n.getLanguage().device;
this.tabNav[0] = this.lanObj.machine;
this.tabNav[1] = this.lanObj.repeater;
},
tabSelect(e) {
this.TabCur = e.currentTarget.dataset.id;
}
},
onLoad() {
},
onShow:function(){
this.refreshLanguage()
}
}
</script>
<style scoped lang="scss">
</style>
- 情形二:切换语言后国际化成功(数据列表定义为对象数组)
<template>
<view>
<view class="bar-nav" style="margin-top: 55px;padding-bottom: 5px;">
<view class="nav-item" :class="index==TabCur? 'nav-text nav-cur':''" v-for="(item,index) in tabNav" :key="index" @tap="tabSelect" :data-id="index">
{{item.name}}
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
lanObj:{},
TabCur: 0,
// tabNav: [this._i18n.getLanguage().device.machine,this._i18n.getLanguage().device.repeater],
tabNav: [
{
"id":0,
"name":this._i18n.getLanguage().device.machine
},
{
"id":1,
"name":this._i18n.getLanguage().device.repeater,
}
]
}
},
methods: {
refreshLanguage:function(){
this.lanObj = this._i18n.getLanguage().device;
// this.tabNav[0] = this.lanObj.machine;
// this.tabNav[1] = this.lanObj.repeater;
this.tabNav[0].name = this.lanObj.machine;
this.tabNav[1].name = this.lanObj.repeater;
},
tabSelect(e) {
this.TabCur = e.currentTarget.dataset.id;
}
},
onLoad() {
},
onShow:function(){
this.refreshLanguage()
}
}
</script>
<style scoped lang="scss">
</style>
1.4 语言切换
<template>
<view class="center">
<view class="center-list">
<navigator url="about" hover-class="navigator-hover">
<view class="center-list-item">
<text class="list-text">{{lanObj.languageSettings}}</text>
<picker style="width: 300upx;" @change="bindPickerChange" :value="index" :range="array" range-key="name">
<view class="uni-input picker-view">{{array[index].name}}</view>
</picker>
</view>
</navigator>
</view>
</view>
</template>
<script>
export default {
data() {
return {
lanObj : {},
index: 0,
array: [{name:'中文'},{name: 'English'}],
}
},
onLoad() {
this.refreshPageLanguage();
},
methods: {
refreshPageLanguage:function(){
// console.log("当前语言为:"+this._i18n.locale)
// console.log(JSON.stringify(this._i18n.locales))
this.lanObj = this._i18n.getLanguage().myhome;
},
bindPickerChange: function(e) {
console.log('picker发送选择改变,携带值为:' + e.detail.value)
this.index = e.detail.value
if(this.index == 0){
this._i18n.setLocale('zh')
}else if(this.index == 1){
this._i18n.setLocale('en')
}
this.refreshPageLanguage();
}
}
}
</script>
<style>
</style>
2. json文件国际化
思路:直接提供翻译的json,然后以一种格式命名,例如 data_zhCN.json,data_enUS.json。然后根据当前使用的语言来加载对应的json文件。
(1) zh.js
{
"dataOfLocalZh": {
"pingParms": [{
"id": "P1",
"name": "起缝速度",
"type":"slider",
"value": "2000",
"min":"1000",
"max":"8000",
"step":"10"
}, {
"id": "P2",
"name": "自由缝最高速度(全局最高限速)",
"type":"slider",
"value": "200000",
"min":"10000",
"max":"250000",
"step":"50"
}],
"baoParms": [{
"id": "P1",
"name": "最高转速",
"type":"slider",
"value": "6000",
"min":"500",
"max":"6000",
"step":"100"
}, {
"id": "P3",
"name": "起缝速度",
"type":"slider",
"value": "500",
"min":"500",
"max":"6000",
"step":"100"
}]
}
}
(2) en.js
{
"dataOfLocalZh": {
"pingParms": [{
"id": "P1",
"name": "Seating speed",
"type":"slider",
"value": "2000",
"min":"1000",
"max":"8000",
"step":"10"
}, {
"id": "P2",
"name": "Free seam maximum speed (global maximum speed limit)",
"type":"slider",
"value": "200000",
"min":"10000",
"max":"250000",
"step":"50"
}],
"baoParms": [{
"id": "P1",
"name": "Maximum speed",
"type":"slider",
"value": "6000",
"min":"500",
"max":"6000",
"step":"100"
}, {
"id": "P3",
"name": "Seating speed",
"type":"slider",
"value": "500",
"min":"500",
"max":"6000",
"step":"100"
}]
}
}
(3) test.vue
<view v-if="machineParms.length > 0" class="container-right">
<view class="item" v-for="(item,index) in machineParms" :key="index">
<view>{{item.name}}</view>
<view v-if="item.type == 'slider' || item.type == 'radio'" @click="showModel(item)">
{{item.value}}
</view>
<view v-if="item.type == 'switch'">
<switch :checked="item.checked" @change="switchChange" color="#04be02" :data-id="item.id"/>
</view>
</view>
</view>
<script>
//import { dataOfLocal } from '@/common/data.json';
import { dataOfLocalZh } from '@/common/data/zh.json';
import { dataOfLocalEn } from '@/common/data/en.json';
export default {
data() {
return {
cate:"6",
machineParms:[],
}
},
methods: {
getLocalData(){
console.log(dataOfLocal);
if(this.cate=="6"){
// this.machineParms = dataOfLocal.pingParms;
if(this._i18n.getLanguage == "zh"){
this.machineParms = dataOfLocalZh.pingParms;
}else{
this.machineParms = dataOfLocalEn.pingParms;
}
} else if(this.cate=="7"){
// this.machineParms = dataOfLocal.baoParms;
if(this._i18n.getLanguage == "zh"){
this.machineParms = dataOfLocalZh.baoParms;
}else{
this.machineParms = dataOfLocalEn.baoParms;
}
}
}
}
</script>