1安装
npm install vue-i18n@next
2在src目录新建 locales-文件夹 (如下图)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/2244ec3f2e7ae707b6349600cf7fd65e.png#pic_center)
3 basic 定义语言包
export default {
login: 'Login',
}
4 helper – 提供 genMessage方法 获取指定文件夹下所有 对象
import { set } from 'lodash-es'
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) {
set(obj, moduleName, obj[moduleName] || {})
set(obj[moduleName], objKey, langFileModule)
} else {
set(obj, moduleName, langFileModule || {})
}
}
})
return obj
}
5 en.js – 封装 英文 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
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)
const defaultLocale = await import(`./lang/${locale.value}.js`)
const message = defaultLocale.default?.message ?? {}
return {
legacy: false,
locale: locale.value,
messages: {
[locale.value]: message,
},
}
}
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 中
<div>{{ t('basic.login') }}</div>
<div>{{ $t('basic.login') }}</div>
9 useLocale --语言切换
import { useLocale } from '@/stores/modules/localeStore'
import { i18n } from './setupI18n'
export const useChangeLocale = async lang => {
const globalI18n = i18n.global
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
if (localeArray.includes(lang)) {
setI18nLanguage(lang, changeLocale)
}
}
const setI18nLanguage = (lang, changeLocale) => changeLocale(lang)
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 同步修改国际化
<template>
<a-config-provider :locale="lang">
<RouterView />
</a-config-provider>
</template>
<script setup>
import { antdLocale } from '@/locales/useLocale'
import { useLocale } from '@/stores/modules/localeStore'
import { storeToRefs } from 'pinia'
import { watch, ref } from 'vue'
const { locale } = storeToRefs(useLocale())
const lang = ref('')
watch(
locale,
async newValue => {
lang.value = await antdLocale(newValue)
},
{ immediate: true }
)
</script>