vue3 i18n 设置国际化 语言切换

39 篇文章 0 订阅
19 篇文章 0 订阅

1安装

 npm install vue-i18n@next

2在src目录新建 locales-文件夹 (如下图)

在这里插入图片描述

3 basic 定义语言包

/**
 *  所有英文 语言包
 */

export default {
	login: 'Login',
}

4 helper – 提供 genMessage方法 获取指定文件夹下所有 对象

/**
 * 提供 genMessage方法 获取指定文件夹下所有 对象
 * basic:{ login: 'login' }
 * basic2:{ login: 'login' }
 *  npm i lodash-es
 */

import { set } from 'lodash-es'

/**
 * langs -- 存放 语言的 所有文件
 * prefix -- 前缀 生成的对象最外键 = prefix 文件夹内文件
 * en文件夹内 -- basic:{ login: 'login' }
 */
export function genMessage(langs, prefix = 'lang') {
	const obj = {}

	Object.keys(langs).forEach(key => {
		const langFileModule = langs[key].default
		let fileName = key.replace(`./${prefix}/`, '').replace(/^\.\//, '')
		const lastIndex = fileName.lastIndexOf('.')
		fileName = fileName.substring(0, lastIndex)
		const keyList = fileName.split('/')
		const moduleName = keyList.shift()
		const objKey = keyList.join('.')

		if (moduleName) {
			if (objKey) {
				// npm i lodash-es
				// set(object, path, value)
				set(obj, moduleName, obj[moduleName] || {})
				set(obj[moduleName], objKey, langFileModule)
			} else {
				set(obj, moduleName, langFileModule || {})
			}
		}
	})
	return obj
}

5 en.js – 封装 英文 message对象

/**
 * 封装 英文 message对象
 * 外层为 messages:{ en:message:{}对象 }
 */

import antdLocale from 'ant-design-vue/es/locale/en_US'
import { genMessage } from '../helper'

const modules = import.meta.glob('./en/**/*.js', { eager: true })

export default {
	message: {
		antdLocale,
		...genMessage(modules, 'en'),
	},
}

6 setupI18n – 生成 i18n

/**
 *  生成 i18n
 * 使用 语言环境 后的对象
 * zh_CN -- { t("从这里开始") }
 */

import { useLocale } from '@/stores/modules/localeStore'
import { storeToRefs } from 'pinia'
import { createI18n } from 'vue-i18n'

// 设置 国际化参数
const createI18nOptions = async () => {
	// 获取语言环境
	const localeStore = useLocale()
	const { locale } = storeToRefs(localeStore)
	// 获取 message对象
	const defaultLocale = await import(`./lang/${locale.value}.js`)
	const message = defaultLocale.default?.message ?? {}

	return {
		// setup中 使用 t ,则需要将其设置为false
		legacy: false,
		// template 使用 $t
		// globalInjection: true,

		locale: locale.value,
		messages: {
			[locale.value]: message,
		},
	}
}
/*
  const messages = {
	en: {
		basic: {
			login: 'login',
		},
	},
}
*/

export let i18n
export const setupI18n = async app => {
	const options = await createI18nOptions()
	i18n = createI18n(options)
	app.use(i18n)
}

7 main 中 使用

// 国际化
import { setupI18n } from '@/locales/setupI18n'

// 引导启动
async function bootstrap() {
	// 创建应用实例
	const app = createApp(App)

	app.use(pinia).use(router)

	await setupI18n(app)
	// 挂载应用
	app.mount('#app')
}

bootstrap()

8 使用

js中

import { useI18n } from 'vue-i18n'

const { t, locale } = useI18n()
console.log(t('basic.login'))
locale.value = "zh_CN"

template 中

// 模版有返回 t 
<div>{{ t('basic.login') }}</div>
// 直接使用
<div>{{ $t('basic.login') }}</div>

9 useLocale --语言切换

/**
 * 语言切换 需要将全部语言提前添加  后续才可以切换
 * 这里采用 切换哪个 添加哪个
 * 1 语言数组 做选择
 * 2 添加对应语言
 * 3 同步修改 pinia
 *
 * export const i18n = createI18n(options)
 * i18n.global === useI18n() = 18
 * 18.availableLocales  多有语言包 名 数组
 * 18.t 全局使用语言函数
 * 18.setLocaleMessage(lang, message)  添加语种
 * 18.locale.value  设置显示语种
 *
 */

// import { unref } from 'vue'
import { useLocale } from '@/stores/modules/localeStore'
import { i18n } from './setupI18n'

export const useChangeLocale = async lang => {
	// 全局对象 切换
	const globalI18n = i18n.global
	// const currentLocale = unref(globalI18n.locale)
	// 要切换的语言 和 现在的相同
	/* 	if (currentLocale === lang) {
		return
	} */

	// 获取语言环境
	const localeStore = useLocale()
	const { localeArray, changeLocale } = localeStore

	const defaultLocale = await import(`./lang/${lang}.js`)
	const message = defaultLocale.default?.message ?? {}
	if (!message) return

	// 添加对应语言
	globalI18n.setLocaleMessage(lang, message)
	// 切换语种
	globalI18n.locale.value = lang
	// 语言池 中 包含 要修改的语言 就更新 pinia
	// 就更新 pinia -- locale
	if (localeArray.includes(lang)) {
		setI18nLanguage(lang, changeLocale)
	}
}
//
const setI18nLanguage = (lang, changeLocale) => changeLocale(lang)

// 导出 a-config-provider 组件所需的 locale -- antdLocale
export const antdLocale = async lang => {
	const defaultLocale = await import(`./lang/${lang}.js`)
	const locale = defaultLocale.default?.antdLocale ?? {}
	return locale
}


10 pinia 缓存 语言变量 与切换语言修改

/**
 *  国际化 缓存 设置 数据
 */

import { defineStore } from 'pinia'
import { reactive, ref } from 'vue'

export const useLocale = defineStore('locale', () => {
	// 国际化 语言 环境
	const locale = ref('en')
	// 所支持的语言池  中文 英文
	const localeArray = reactive(['zh_CN', 'en'])

	const changeLocale = str => {
		locale.value = str
	}
	// 返回
	return { locale, localeArray, changeLocale }
})

11 切换语言

<!--
* @author wn
* @date 2023/02/27 11:14:27
* @description: 语言切换组件
!-->
<template>
	<!-- v-model:value="$i18n.locale" -->
	<a-space>
		<a-select v-model:value="lang" style="width: 70px" @change="handleChange">
			<a-select-option
				v-for="(item, index) in localeArray"
				:key="index"
				:value="item"
				>{{ item === 'zh_CN' ? '中文' : item }}
			</a-select-option>
		</a-select>
	</a-space>
</template>
<script setup>
import { useLocale } from '@/stores/modules/localeStore'
import { storeToRefs } from 'pinia'
import { useChangeLocale } from '@/locales/useLocale'
import { ref } from 'vue'

const { locale, localeArray } = storeToRefs(useLocale())
// 默认语言
const lang = ref(locale.value)
// 点击切换语言
const handleChange = value => useChangeLocale(value)
</script>
<style scoped lang="less"></style>

12 Ant D 同步修改国际化

// useLocale 中  antdLocale

// App.vue

<template>
	<a-config-provider :locale="lang">
		<RouterView />
	</a-config-provider>
</template>
<script setup>
// 导入 对应 组件所需的 locale
import { antdLocale } from '@/locales/useLocale'

import { useLocale } from '@/stores/modules/localeStore'
import { storeToRefs } from 'pinia'
import { watch, ref } from 'vue'

const { locale } = storeToRefs(useLocale())

// 根据 store  获得 对应 lang
// 切换语言的 同时 切换组件 国际化
const lang = ref('')
watch(
	locale,
	async newValue => {
		lang.value = await antdLocale(newValue)
	},
	{ immediate: true }
)
</script>
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值