前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >vue3实现国际化

vue3实现国际化

作者头像
zhouzhouya
发布2023-10-26 17:25:47
5250
发布2023-10-26 17:25:47
举报
文章被收录于专栏:一名前端开发一名前端开发

很多情况下要求代码支持国际化。看了文档及查阅资料。现将代码支持国际化的流程整理如下(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')
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-10-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.安装vue-i18n(vue3的话安装最新版本,否则可能会报错)
  • 2. 在utils文件下创建misc.js(此例子支持中文,英文,繁体,若想支持其他语言可配置相应语言)
  • 3.在src目录下创建locales文件夹,在locales文件夹下创建index.js
  • 4. 在locales文件夹下创建zh-CN.js(存放字典的js文件)
  • 5. 在locales文件夹下创建zh-TW.js(存放字典的js文件)
  • 6. 在locales文件夹下创建en.js(存放字典的js文件)
  • 7. 最后在main.js文件中引入
  • 8.路由和面包屑国际化
  • 9.在script中使用国际化
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档