# I18n 多语言切换

本教程旨在指导您在uni-app(小程序,H5,APP(不含NVUE)等)中从0开始,到熟练使用多语言切换功能,在这里,我们使用的是vue-i18n插件,请您务必按照我们提供的步骤,完整的做好每一步的配置。

前言:

  • i18n是一个专门用于处理多语言的插件,其义来自于internationalization(国际化),取其首尾两个字母in,中间部分nternationalizatio刚好18个字母, 故被起名i18n
  • 此插件非uView内置功能,您需要通过npm下载方可使用。

温馨提示

uView精心为您准备了一个多语言切换的工程,包含了本文的所有演示功能,在下载页找到对应资源下载运行即可:资源下载 (opens new window)

# 安装vue-i18n

您需要通过npm安装此插件:

// 如果您的项目由HX创建,根目录没有package.json的话,先通过如下命令创建package.json
// npm init -y

// 安装vue-i18n
npm install vue-i18n
✅ Copy success!

# 在main.js中引用vue-i18n

// 原有内容
import Vue from 'vue'
import App from './App'


// 以下为添加的内容

// 引入语言包,注意路径
import zh from '@/common/locales/zh.js';
import en from '@/common/locales/en.js';

// 引入并使用vue-i18n
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)

// 构造i18n对象
const i18n = new VueI18n({
	// 默认语言,这里的local属性,对应message中的zh、en属性
	locale: 'zh',
	// 引入语言文件
	messages: {
		// 这里的属性名是任意的,您也可以把zh设置为cn等,只是后续切换语言时
		// 要标识这里的语言属性,如:this.$i18n.locale = zh|en|zh|xxx
		'zh': zh, // 这里为上面通过import引入的语言包
		'en': en,
	}
})

// 由于微信小程序的运行机制问题,需声明如下一行,H5和APP非必填
Vue.prototype._i18n = i18n


// 原有内容,需在这添加i18n
const app = new Vue({
	// 记得在这添加i18n
	i18n,
	store,
    ...App
})
✅ Copy success!

注意

别忘了上面的最后处,需要在new Vue构造器中写入i18n

# 定义语言包

上面我们在main.js通过import引入了两个语言包,一般来说,需要多少种语言,就要有多少个语言包,建议语言包中通过定义不同的字段划分不同页面 所属的素材:

// zh.js
export default {
	// 可以以页面为单位来写,比如首页的内容,写在index字段,个人中心写在center,公共部分写在common部分
	lang: {
		title: 'uView UI',
		intro: '多平台快速开发的UI框架',
	},
	common: {
		// ......
	},
	index: {
		// ......
	}
}
✅ Copy success!

# 使用

在实际场景中,我们可能在js中,也有可能在模板中使用,需通过$t('lang.title')的形式引用,这里的lang是我们上一步zh.js中定义的lange字段,title 自然而然就是lang对象的title属性了。

<template>
	<view style="margin-top: 200rpx;">
		{{$t('lang.intro')}}
	</view>
</template>

<script>
	export default {
		onLoad() {
			console.log(this.$t('lang.intro'));
		}
	}
</script>
✅ Copy success!

# 语言切换

当我们点击语言切换的时候,通过this.$i18n.locale来设置新的语言,这个语言是我们定义在main.js中的message属性:

回顾:我们上面第二步在main.js中进行了如下设置,其中的message对象的zhen就是我们所能切换的语言:

// main.js
// 构造i18n对象
const i18n = new VueI18n({
	// 默认语言,这里的local属性,对应message中的zh、en属性
	locale: 'zh',
	// 引入语言文件
	messages: {
		// 这里的属性名是任意的,您也可以把zh设置为zh等,只是后续切换语言时
		// 要标识这里的语言属性,如:this.$i18n.locale = zh|en|zh|xxx
		'zh': Chinese,
		'en': English,
	}
})
✅ Copy success!

语言切换:

<template>
	<view style="margin-top: 200rpx;">
		{{$t('lang.intro')}}
		<u-button @click="switchLang">切换语言</u-button>
	</view>
</template>

<script>
	export default {
		onLoad() {
			console.log(this.$t('lang.intro'));
		},
		methods: {
			switchLang() {
				// 切换为英文
				this.$i18n.locale = 'en';
			}
		}
	}
</script>
✅ Copy success!

# 双向绑定的陷阱

有时候,我们可能需要给data中的属性赋值多语言的值,很遗憾当您切换语言时会发现这是无法双向绑定的,体现在语言切换了,但是视图并没有更新。 这本质上是因为data中的属性是一次性赋值的,解决办法是在computed中定义相关的变量。

<template>
	<view style="margin-top: 200rpx;">
		{{intro}}
		<u-button @click="switchLang">切换语言</u-button>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				// 错误示例,切换语言时,这个intro并不会自动更新到视图
				// intro: this.$t('lang.intro')
			}
		},
		computed: {
			// 正确用法
			intro() {
				return this.$t('lang.intro')
			}
		},
		methods: {
			switchLang() {
				this.$i18n.locale = 'en';
			}
		}
	}
</script>
✅ Copy success!

# 难点

上面我们解决了如何引入插件,定义和使用语言包,但是我们依然会碰到如下几个难点:

  • 如果我需要在js中判断当前语言,进行不同的页面跳转怎么办?
  • 如何修改导航栏的标题?
  • 如何修改底部Tabbar导航的文字?

没关系,uView已经为您提供了完善的解决方案:

# 1. 如果我需要在js中判断当前语言,进行不同的页面跳转怎么办?

这个其实很简单,我们只需通过this.$i18n.locale就能获取当前的语言名称。当然,您也可以将当前的语言变量放到一个全局变量中, 关于全局变量,详见我们的另一个专题:全局变量的实现方式

# 2. 如何修改导航栏的标题?

修改原生导航栏,我们需要通过uni.setNavigationBarTitle()进行,既然是调用uni的接口,意味着我们无法通过双向绑定,切换语言时自动更新导航栏标题,所以 我们需要在onShow生命周期调用此接口,当每次页面出现在窗口时,重新设置导航栏(不管语言是否切换):

<template>
	<view style="margin-top: 200rpx;">
		{{$t('lang.intro')}}
		<u-button @click="switchLang">切换语言</u-button>
	</view>
</template>

<script>
	export default {
		// 在onShow生命周期设置导航栏标题
		onShow() {
			uni.setNavigationBarTitle({
				title: this.$t('lang.title')
			});
		},
		methods: {
			switchLang() {
				this.$i18n.locale = 'en';
				// 当您切换了语言之后,并不会触发onShow生命周期,意味着本页的标题不会马上
				// 变更,所以我们需要在切换了语言之后,手动执行一遍设置标题的接口
				uni.setNavigationBarTitle({
					title: this.$t('lang.title')
				});
			}
		}
	}
</script>
✅ Copy success!

# 3. 如何修改底部Tabbar导航的文字?

我们可以通过uni.setTabBarItem()设置单个的Tabbar Item,这很简单,我们在切换语言的地方,将所有的item设置一遍即可:

<template>
	<view style="margin-top: 200rpx;">
		<u-button @click="switchLang">切换语言</u-button>
	</view>
</template>

<script>
	export default {
		methods: {
			switchLang() {
				this.$i18n.locale = 'en';
				// uni.setTabBarItem接口详见:https://uniapp.dcloud.io/api/ui/tabbar?id=settabbaritem
				// 说明:这种方法不适用自定义tabbar,自定义tabbar请自行根据逻辑调整
				// 注意:【支付宝小程序开发工具】需要1.13版本才支持此接口的模拟,真机预览不受限制
				uni.setTabBarItem({
					index: 0,
					text: this.$t('tabbar.index'),
				})
				uni.setTabBarItem({
					index: 1,
					text: this.$t('tabBar.news'),
				})
				uni.setTabBarItem({
					index: 2,
					text: this.$t('tabBar.center'),
				})
			}
		}
	}
</script>
✅ Copy success!

# 写在最后

通过上面的教程,相信您已经对多语言切换有了全面的认识,但不止于此,因为uView对您的爱是无微不至的,我们为您准备了一个完整的示例,下载运行即可,快试试吧!

点击下载:https://download.uviewui.com/i18n.zip (opens new window)