vue多语言国际化实战

前言

  • 常网IT源码上线啦!
  • 本篇录入技术选型专栏,希望能祝君拿下Offer一臂之力,各位看官感兴趣可移步🚶。
  • 有人说面试造火箭,进去拧螺丝;其实个人觉得问的问题是项目中涉及的点 || 热门的技术栈都是很好的面试体验,不要是旁门左道冷门的知识,实际上并不会用到的。
  • 接下来想分享一些自己在项目中遇到的技术选型以及问题场景。

香烟上瘾~

大部分人根本不知道为什么尼古丁能让他们愉悦,产生快乐的体感?他们以为迷恋的是烟草的味道,根本上来说他们想要的是多巴胺的分泌。

而这种物质,除了在香烟中获得,适当的运动、充足的睡眠、音乐以及光合作用同样能够得到。

但是他们无法坚持去体验后者,甚至是不情愿的。

因为有速成,为什么要去做麻烦,花时间、花精力的事情呢?

陆陆续续下了快六个月了~

一、需求

今天像以往一样,打开VS CODE开开心心的编码,是新项目,于是心血来潮。

领导走过去,这项目要支持多语言啊,记得🙏。

心想,也不是很难,我们像以往一样,分析一下技术的多样解决方案。

二、vue-i18n

我相信😊 ,大家第一个想到的就是它vue-i18n

2.1 安装

这个版本比较稳定。

java 复制代码
npm install vue-i18n@8.26.7 -S

2.2 main.js

我们要考虑elementUi也要支持国际化语言。

ElementLocale导入了 Element UI 组件库的本地化(Locale)模块。这个模块通常用于管理 Element UI 组件库中各种组件的语言国际化功能。

通过导入 ElementLocale,你可以在代码中使用这个模块提供的方法来设置和管理 Element UI 组件的国际化相关配置,包括日期格式、文字内容、提示信息等。

java 复制代码
import ElementLocale from 'element-ui/lib/locale'

还要考虑B被A嵌入的情况下。

这是main的完整代码,如下:

java 复制代码
import i18n from './i18n'

import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

// ElementLocale
import ElementLocale from 'element-ui/lib/locale'

// 饿了么ui支持国际化
Vue.use(ElementUI,{
	i18n:(key,value)=>i18n.t(key,value)
});

// 这是B项目,被A项目主框架嵌入,的情况下
//新增il8n对象
let zhMOObject = Object.assign({}, app.$i18n.messages['zh-MO'],i18n.messages['zh-MO'])	// app的是A主框架,后面的i18n是B项目,合并
let ptPTObject = Object.assign({}, app.$i18n.messages['pt-PT'],i18n.messages['pt-PT'])
app.$i18n.setLocaleMessage('zh-MO', zhMOObject)	//进行重新设置
app.$i18n.setLocaleMessage('pt-PT', ptPTObject)

ElementLocale.i18n((key, value) => app.$i18n.t(key, value))	// 饿了么的也要重新设置(以主框架app为准)


new Vue({
  router,
  store,
  i18n,	// 引入vue中
  render: (h) => h(App)
}).$mount('#app')

2.3 请求通知后端

request.js请求,在请求接口的时候,我加个请求头告诉后台返回语言。

这一点可能大家觉得没必要,但是是要的- 🥰。

接口也会做国际化,返回的信息。

java 复制代码
service.interceptors.request.use(
    config => {
      // 这里加入语言包的请求头
      config.headers['lang'] = localStorage.getItem("i18nLocale") || "zh-MO"
      if (config.vue) {
        config.vue.loading = true
        config.vue.loadfailed = false;
      }
    
      config.params = {
        t: new Date().getTime(),
        ...config.params
      }
			return config
    },
    error => {
      return Promise.reject(error)
    }
  )
      

2.4 il8n

i18n/index.js

java 复制代码
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import zh_TW from './lang/zh-TW.js'
import pt from './lang/pt.js'
import zhTWLocale from "element-ui/lib/locale/lang/zh-TW"; //引入element语言包
import ptLocale from "element-ui/lib/locale/lang/pt"; //引入element语言包

Vue.use(VueI18n)

const messages = {
  "zh-MO": Object.assign(zh_TW,zhTWLocale),//繁体
  "pt-PT": Object.assign(pt,ptLocale),//葡文
}

export function getLanguage(){ 
  const language  = localStorage.getItem("i18nLocale") || "zh-MO"
  const locales = Object.keys(messages)
  for(const locale of locales){
    if(language.indexOf(locale)>-1){
      return locale
    }
  }
  return "zh-MO"
}

const i18n = new VueI18n({
  locale: localStorage.getItem("i18nLocale") || "zh-MO", // 默认语言标识
  silentTranslationWarn: true,
  silentFallbackWarn: true,
  messages,
})
export default i18n

pt.js和zh-TW.js

java 复制代码
export default {
	login: {
    userName: "用戶",
    password: "密碼",
    login: "登錄",
    logining: "正在登錄",
  },
  ...后面还有
}

2.5 store.js

可以发现 i18n/index.js有个方法 getLanguage是为了给 store.jsvuex用的。

java 复制代码
import { getLanguage } from '@/i18n'

const app = {
  state: {
    language: getLanguage(),
  },
  mutations: {
    set_language(state, language){
      state.language = language
    }
  },
  actions: {
    set_language({ commit }, language){
      commit('set_language', language)
    }
  },
  getters: {
    language: state => state.language,
  }
}

export default app

2.6 使用

java 复制代码
<div>
  {{ $t('login.userName') }}
</div>

2.7 扩展:如果不让用户改localStorage的语言

因为我都是存在localStorage中的,我只需要监听值的修改,😻不让他修改即可。

可以使用类似之前提到的自定义事件机制,在应用程序中监听 localStorage 的变化。当检测到 localStorage 值的变化时,可以进行相应的处理,例如校验或重新加载数据。

以下代码:对 localStorage.setItem 方法进行了修改,添加了一个事件触发机制,以便在设置 localStorage 值时触发自定义事件 localStorageChange。

localStorage的storage事件只有在其他窗口或标签页手动修改localStorage的值时才会触发。这是为了确保安全性和隐私性,以防止网站在不明示用户许可的情况下监视本地存储的更改。

java 复制代码
/**
 * 重写localStorage.setItem方法监听localStorage值的改变
 */
function overrideLocalStorageSetItemWithChangeEvent(){
    const originalSetItem = localStorage.setItem;
    localStorage.setItem = function(key, newValue) {
        const event = new Event('localStorageChange');
        event.key=key;
        event.newValue = newValue;
	// 使用 window.dispatchEvent 方法触发自定义事件 localStorageChange,将事件对象传递给 dispatchEvent 方法。
        window.dispatchEvent(event);	
        originalSetItem.apply(this, arguments)	// 使用 originalSetItem.apply(this, arguments) 调用原始的 localStorage.setItem 方法,确保 localStorage 的值正常被设置。
    }
}

// 监听自定义事件
window.addEventListener('localStorageChange', function(event) {
  if(event.key==="i18nLocale"){
    // alert(`localStorage键 "${event.key}" 的值已设置为 "${event.newValue}"`)
  }
});

其实就是重写setItem,这样子有人手动改了localStorage的值,我根据我的重写会监听到,在localStorageChange函数中,那我只需要,不将新的值设置进去。

那我想自己改怎么办?

你小子。。

用到数字签名,如果值是对的,我让他set进去,不对(如果签名无效,则说明数据已被篡改),就忽略。

我可以生成个唯一标识,是加密的,解密后值对了,才让他set进去。

三、其他技术实现

你说,我不想引入插件实现,有其他方法吗?

yes。

使用 Vuex 管理多语言状态

你可以将当前语言状态存储在 Vuex 中,并通过 Vuex 管理语言切换的行为。

当然就要自己手动实现。

使用 JSON 文件管理翻译

将不同语言的翻译内容存储在 JSON 文件中,然后根据当前语言动态加载相应的 JSON 文件。这种方法使得维护和管理翻译文本更加灵活。

存在服务器就可以随时改动。

至此撒花🌷🌷~

后记

我们在实际项目中或多或少遇到一些技术方案的思考。

但技术上的选项,需要我们对每一个都了如指掌,方可选择。

没有最好,只有适合。

如果有其他更好的方法也欢迎评论区见,这里提供的只是诸多方法之一。

最后,祝君能拿下满意的offer。

我是Dignity_呱,来交个朋友呀,有朋自远方来,不亦乐乎呀!深夜末班车

👍 如果对您有帮助,您的点赞是我前进的润滑剂。

以往推荐

小小导出,我大前端足矣!

靓仔,说一下keep-alive缓存组件后怎么更新及原理?

面试官问我watch和computed的区别以及选择?

面试官问我new Vue阶段做了什么?

前端仔,快把dist部署到Nginx上

多图详解,一次性啃懂原型链(上万字)

Vue-Cli3搭建组件库

Vue实现动态路由(和面试官吹项目亮点)

项目中你不知道的Axios骚操作(手写核心原理、兼容性)

VuePress搭建项目组件文档

原文链接

juejin.cn/post/738692...

相关推荐
轻口味9 分钟前
【每日学点鸿蒙知识】AVCodec、SmartPerf工具、web组件加载、监听键盘的显示隐藏、Asset Store Kit
前端·华为·harmonyos
alikami12 分钟前
【若依】用 post 请求传 json 格式的数据下载文件
前端·javascript·json
吃杠碰小鸡1 小时前
lodash常用函数
前端·javascript
emoji1111111 小时前
前端对页面数据进行缓存
开发语言·前端·javascript
泰伦闲鱼1 小时前
nestjs:GET REQUEST 缓存问题
服务器·前端·缓存·node.js·nestjs
m0_748250031 小时前
Web 第一次作业 初探html 使用VSCode工具开发
前端·html
一个处女座的程序猿O(∩_∩)O1 小时前
vue3 如何使用 mounted
前端·javascript·vue.js
m0_748235951 小时前
web复习(三)
前端
迷糊的『迷』1 小时前
vue-axios+springboot实现文件流下载
vue.js·spring boot
web135085886351 小时前
uniapp小程序使用webview 嵌套 vue 项目
vue.js·小程序·uni-app