很多情况下要求代码支持国际化。看了文档及查阅资料。现将代码支持国际化的流程整理如下(vue版本3.2.27)
1.安装vue-i18n(vue3的话安装最新版本,否则可能会报错)
代码语言:javascript复制npm install vue-i18n@next
2. 在utils文件下创建misc.js(此例子支持中文,英文,繁体,若想支持其他语言可配置相应语言)
代码语言:javascript复制function useIE() {
// for Now, detect IE 11 and Edge only, other IE version will has no support
return (navigator.appName === 'Microsoft Internet Explorer'
|| !!(navigator.userAgent.match(/Trident/)
|| navigator.userAgent.match(/rv:11/)
|| navigator.userAgent.match(/Edge/)));
}
function isEllipsisActive(elem) {
// Check whether text ellipsis is active
return elem.offsetWidth < elem.scrollWidth;
}
function getRemoteFile(res) {
if (!res) {
return null;
}
const head = res.headers['content-disposition'];
const type = res.headers['content-type'];
const blob = new Blob([res.data], { type });
let filename = head.split(';')[1].split('=')[1];
const reg = new RegExp('"', 'g');
filename = filename.replace(reg, '');
return ({
blob, filename,
});
}
function downloadRawFile(blobData, filename) {
if (blobData != null && navigator.msSaveBlob) {
navigator.msSaveBlob(blobData, filename);
return;
}
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blobData);
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
window.URL.revokeObjectURL(link.href);
document.body.removeChild(link);
}
function getBrowserLanguage() {
const browserLanguage = window.navigator.language;
console.log('browserLanguage: ', browserLanguage);
// const validZHTW = ['zh-TW', 'zh-CN','en'];
// console.log(i18n)
return browserLanguage? browserLanguage : 'zh-CN';
}
function checkLanguage(locale) {
const BaseLanguage = ['zh-CN', 'en','zh-TW'];
return BaseLanguage.find(i18n => i18n === locale) || 'zh-CN';
// return validZHTW.find(i18n => i18n === browserLanguage) ? 'zh-TW' : 'zh-CN';
}
// eslint-disable-next-line
document.head || (document.head = document.getElementsByTagName('head')[0]);
function changeFavicon(src) {
const link = document.createElement('link');
const oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = src;
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
}
const passKeys = [
16, // shift
17, // ctrl
18, // alt
91, // meta
93, // meta
9, // tab
20, // caps lock
];
// e is keyboard event, check if press controll key only
function controlKeyOnly(e) {
for (let i = 0; i < passKeys.length; i = 1) {
if (e.keyCode === passKeys[i]) {
return true;
}
}
return false;
}
function recognizeJSDataType(obj) {
let classToType;
if (!classToType) {
classToType = {};
['Boolean', 'Number', 'String', 'Function', 'Array', 'Date', 'RegExp', 'Object', 'Error'].forEach((e) => {
classToType[`[object ${e}]`] = e.toLowerCase();
});
}
if (obj === null) {
return 'null';
}
if (typeof obj === 'object' || typeof obj === 'function') {
return classToType[classToType.toString.call(obj)] || 'object';
}
return typeof obj;
}
function setPageTitle(name) {
document.title = name;
}
function openWin(url, name, iWidth, iHeight) {
const iTop = (window.screen.availHeight - 30 - iHeight) / 2;
const iLeft = (window.screen.availWidth - 10 - iWidth) / 2;
// eslint-disable-next-line
window.open(url, name, 'height=' iHeight ',innerHeight=' iHeight ',width=' iWidth ',innerWidth=' iWidth ',top=' iTop ',left=' iLeft ',status=no,toolbar=no,menubar=no,location=no,resizable=no,scrollbars=0,titlebar=no');
}
export default {
useIE,
isEllipsisActive,
getRemoteFile,
downloadRawFile,
controlKeyOnly,
getBrowserLanguage,
recognizeJSDataType,
setPageTitle,
changeFavicon,
checkLanguage,
openWin,
};
3.在src目录下创建locales文件夹,在locales文件夹下创建index.js
代码语言:javascript复制import { createI18n } from "vue-i18n";
import zh from "./zh-CN";
import en from "./en";
import tw from "./zh-TW"
import misc from '@/utils/misc';
let locale = localStorage.getItem('locale');
console.log('locale: ', locale);
console.log('locale: ', !locale === true);
if (!locale) {
locale = misc.getBrowserLanguage();
console.log('locale: ', locale);
// locale = 'zh-CN';
localStorage.setItem('locale', locale);
}
// locale = misc.checkLanguage(locale);
// localStorage.setItem('locale', locale);
const i18n = createI18n({
locale: locale, // 定义默认语言为中文
legacy: false,
globalInjection: true,
messages: {
'zh-CN': zh,
'zh-TW': tw,
en,
},
});
export default i18n;
// {{ t('header_menu.logout') }}
4. 在locales文件夹下创建zh-CN.js(存放字典的js文件)
代码语言:javascript复制export default {
"welcomeToUse": "欢迎使用i18n",
"login": "登录"
};
5. 在locales文件夹下创建zh-TW.js(存放字典的js文件)
代码语言:javascript复制export default {
"welcomeToUse": "欢迎使用i18n",
"login": "台湾繁体"
};
6. 在locales文件夹下创建en.js(存放字典的js文件)
代码语言:javascript复制export default {
"welcomeToUse": "welcomeToUse.i18n",
"login": "login"
};
7. 最后在main.js文件中引入
代码语言:javascript复制import I18n from "./locales/index"
app.use(I18n);
8.路由和面包屑国际化
在国际化过程中会遇到路由和面包屑的国际化。在router中,跟i18n对象是同级传入new Vue()的,router无法获取i18n信息,因为国际化的方式则为:
代码语言:javascript复制router下的路由规则文件(改变title的写法)
{
path: '/scriptlibrary',
component: () => import('@/views/Scriptlibrary/index'),
meta: {
title: 'router.scriptlibrary',
icon: "@scriptlibrary",
activeMenu: '/scriptlibrary'
},
redirect: "/scriptlibrary/list",
children: [
{
path: '/scriptlibrary/list',
name: "Scriptlibrary",
component: () => import('@/views/Scriptlibrary/List'),
meta: {
title: 'router.scriptlibrary',
icon: "@scriptlibrary",
},
},
{
path: '/scriptlibrary/scriptdetails',
component: () => import('@/views/Scriptlibrary/ScriptDetails'),
meta: {
title: 'router.scriptdetails',
// icon: "ScriptDetails",
},
hidden: true,
},
]
},
代码语言:javascript复制获取导航栏的写法不同($t(item.meta.title) ,面包屑同理)
<el-menu-item
:index="resolvePath(onlyOneChild.path)"
:class="{ 'submenu-title-noDropdown': !isNest }"
>
<svg-icon :icon-class="item.meta.icon.slice(1)" v-if="iconSubType(item) === 1"></svg-icon>
<el-icon v-else-if="iconSubType(item) === 2">
<component :is="item.meta.icon"></component>
</el-icon>
<template #title>
<span class="title">{{ $t(item.meta.title) }}</span>
</template>
</el-menu-item>
9.在script中使用国际化
代码语言:javascript复制引入
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
使用
t('scriptlibrary.importDrawer.success')