# I18n 多语言切换 3.5.0

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

温馨提示

uview-plus内置的多语言支持无侵入,无依赖,自动使用uni-app的uni.getLocale()方法获取到的语言,并自动切换,因此只需要项目中使用uni.setLocale()方法设置语言,即可实现uview-plus内置组件的多语言切换。

前言:

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

# 安装vue-i18n

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

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

// 安装vue-i18n
npm install vue-i18n

# 在main.js中引用vue-i18n

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


// 以下为添加的内容

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

// 引入并使用vue-i18n
import { createI18n } from 'vue-i18n'// v9.x

// 构造i18n对象
const i18n = createI18n({
	// 默认语言,这里的local属性,对应message中的zh、en属性
	locale: uni.getLocale(),// 获取已设置的语言
	// 引入语言文件
	messages: {
		// 这里的属性名是任意的,您也可以把zh设置为cn等,只是后续切换语言时
		'zh-Hans': zhHans, // 这里为上面通过import引入的语言包
		'en': en,
	}
})


// 原有内容,需在这添加i18n
import { createSSRApp } from 'vue'
export function createApp() {
  const app = createSSRApp(App)

  app.use(uviewPlus)
	.use(i18n)
  return {
    app
  }
}

# 定义语言包

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

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

# 使用

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

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

<script setup>
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
</script>

# 语言切换

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

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

// main.js
// 构造i18n对象
const i18n = new VueI18n({
	locale: uni.getLocale(),// 获取已设置的语言
	// 引入语言文件
	messages: {
		// 这里的属性名是任意的,您也可以把zh设置为zh等,只是后续切换语言时
		// 要标识这里的语言属性,如:this.$i18n.locale = zh|en|zh|xxx
		'zh-Hans': Chinese,
		'en': English,
	}
})

语言切换:

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

<script setup>
	const switchLang = () => {
		uni.setLocale('en')
	}
</script>

# 双向绑定的陷阱

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

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

<script>
	import { useI18n } from 'vue-i18n'
	const { t } = useI18n()
	export default {
		data() {
			return {
				// 错误示例,切换语言时,这个intro并不会自动更新到视图
				// intro: t('lang.intro')
			}
		},
		computed: {
			// 正确用法
			intro() {
				return t('lang.intro')
			}
		},
		methods: {
			switchLang() {
				uni.setLocale('en')
			}
		}
	}
</script>

# 难点

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

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

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

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

这个其实很简单,我们只需通过uni.getLocale()就能获取当前的语言名称。

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

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

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

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

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

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

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

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

# 写在最后

通过上面的教程,相信您已经对多语言切换有了全面的认识,但不止于此,你还可以参考https://uniapp.dcloud.net.cn/tutorial/i18n.html