前言
- 常网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.js
vuex用的。
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_呱,来交个朋友呀,有朋自远方来,不亦乐乎呀!深夜末班车
👍 如果对您有帮助,您的点赞是我前进的润滑剂。