参考文章:
https://zhuanlan.zhihu.com/p/694648355
基本步骤:
- 定义语言包文件:需要几种语言,就定义几个语言包文件,如zh.js、en.js
- 配置messages属性值:在i18n配置文件中,创建语言包索引对象(?),“键-值”对应“语言包名字-语言包文件”
- 创建并配置createI18n对象:在i18n配置文件中,messages属性值为上一步配置的对象,local为当前使用的语言,从浏览器的sessionStorage中获取键为’language_type’的数据。
- 全局注册:main.js文件中引入i18n配置文件,app.use()全局注册、app.mount()挂载
1.定义语言包文件
两种推荐文件夹划分:
(与src同级)
①public/i18n/zh.js
②locale/lang/zh.js
zh.js文件:
//默认暴露,后续需要在i18n配置文件中引入
export default {
//系统通用的字段放一个对象
"message":{
"add":"添加",
"delete":"删除",
...
},
//比较独立的一个功能模块的字段放一个对象
"personal":{
"name":"名称",
...
},
...
}
如法炮制定义其他语言包的文件
2. 创建并配置createI18n对象
新建i18n具体配置文件,推荐文件管理:
src/language/i18n.js
具体代码:
import { createI18n } from 'vue-i18n'
import zh from '../../public/i18n/zh'
import en from '../../public/i18n/en'
// 创建并配置i18n
const i18n = createI18n({
legacy: false, // 是否启用旧版i18n,没有该参数可能会报错
locale: sessionStorage.getItem('language_type') ? sessionStorage.getItem('language_type') : 'zh', //zh是中文,en是英文
messages: {
zh, //ES6语法,键值对省略写法
en
}
})
//默认暴露i18n对象
export default i18n
3.全局注册
main.js中全局注册插件
// 国际化组件
import i18n from '@/language/i18n'
const app = createApp(App)
app
.use(i18n)
.mount('#app')
非本地语言包
以上是使用本地语言包的方法,如果语言包需要网络请求获取,应该如何配置?
①网络请求函数:网络请求获取语言包文件,并处理成合适的格式
②添加语言包函数:获取当前语言类型,调用网络请求函数,利用i18n.global.setLocaleMessage()设置messages
③调用以上函数,处理失败情况
i18n.js完整代码:
import { createI18n } from 'vue-i18n'
import zh from '../../public/i18n/zh'
import en from '../../public/i18n/en'
import axios from 'axios'
// 请求获取语言文件
const getLangJS = (language) => {
return new Promise((resolve, reject) => {
axios({
url: `语言包所在地址/${language}.js`,
responseType: 'arraybuffer' //二进制形式
}).then(res => {
// 从服务器获取二进制数组数据,将其转换为Blob对象
// 创建Blob URL,通过动态import加载JavaScript模块
// 获取加载的模块默认导出内容
// 与语言类型一起作为成功的结果对象传递给Promise对象
const arrayBuffer = res.data;
const blob = new Blob([arrayBuffer], {
type: 'application/javascript'
});
const blobURL = URL.createObjectURL(blob);
import(/* @vite-ignore */blobURL).then(module => {
const context = module.default;
resolve({ lang, context })
}).catch(e => {
reject(e)
})
}).catch(err => {
reject(err)
})
})
}
// 创建并配置i18n
const i18n = createI18n({
legacy: false, // 没有该参数可能会报错
locale: sessionStorage.getItem('language_type') ? sessionStorage.getItem('language_type') : 'zh', //zh是中文,en是英文
messages: {
// zh,
// en
}
})
// 添加请求语言到i18n中
const addLangJS = async () => {
let promiseList = []
let locale = sessionStorage.getItem('language_type') ? sessionStorage.getItem('language_type') : 'zh'
promiseList.push(getLangJS(locale));
let flag = false
await Promise.all(promiseList).then(res => {
flag = true
res.map(v => {
i18n.global.setLocaleMessage(v.lang, v.context);
})
}).catch(err => {
flag = false
})
return flag
}
// 调用添加函数并处理失败情况
if (!await addLangJS()) {
if (i18n.global.locale.value === 'zh') {
ElMessage.error('语言文件配置错误')
} else {
ElMessage.error('LANGUAGE FILE CONFIGURATION ERROR!')
}
}
export const useI18n = i18n.global;
export default i18n
知识补充
Blob对象
Blob对象表示了一个不可变的、原始数据的类文件对象,这里将二进制数组数据转换为Blob对象,并指定了其MIME类型为application/javascript。
MIME 类型(Multipurpose Internet Mail Extensions)
是一种标准化的方式,用于指示互联网上的文件类型和格式。在这种情况下,application/javascript MIME 类型用于表示传输的数据是 JavaScript 脚本文件。
当浏览器接收到一个带有 application/javascript MIME 类型的响应时,它会将这个响应解析为 JavaScript 脚本,按照 JavaScript 的语法规则来解析和执行这些数据。这通常用于加载外部的 JavaScript 文件,例如通过动态加载脚本或通过
import
import(/* @vite-ignore */blobURL).then(
module => {
const context = module.default;
resolve({ lang, context })
})
:使用动态import语法加载通过Blob URL加载的JavaScript模块。@vite-ignore是用于告诉Vite编译器忽略对这个URL的处理。当模块加载成功后,获取模块的默认导出内容,并将其存储在context变量中。