国际化动态加载数据
起因
公司业务涉及比较广泛,所做网页必然要涉及到国际化;国际化本是老生常谈的内容,但是我们大部分做的都是静态数据国际化;或者联网插件国际化。而很多公司,属于内网开发,故而只能静态数据;但是整个项目很大,很多时候静态数据太多放置前端也不方便;所以才有动态化加载国际化数据。
思路
一开始做动态国际化,我想的是在i18n的index.js文件中去做事件监听;每个页面请求数据时,我将它处理后push在vuex里储存起来。监听到储存值后就直接加到对应的en.js和zh.js文件中。但是,i18n不能监听和computed;然后我想了好久,官网上也没有类似demo,只有几个api;其中有一个mergeLocaleMessage吸引了我,我就寻思能不能用这个去做,获取页面数据,数据处理,储存vuex,然后储存的时候把它合并到i18n里面去;想法有了就直接开整!上代码:
代码:
vuex的数据:
state: {
ws_progress: getStore({ name: 'ws_progress' }) || '0% ', //进度条
languageGatherZh: JSON.parse(localStorage.getItem('languageGatherZh')) || [],//中文集合
languageGatherEn: JSON.parse(localStorage.getItem('languageGatherEn')) || [],//英文集合
},
mutations: {
SET_LANGUAGE_ZH: (state, obj) => {
state.languageGatherZh.push(obj);
const uniqueArr = uniqueArray(state.languageGatherZh) //数组去重
localStorage.setItem('languageGatherZh', JSON.stringify(uniqueArr))
uniqueArr.forEach(item => {
i18n.mergeLocaleMessage('zh', item)
});
},
SET_LANGUAGE_EN: (state, obj) => {
state.languageGatherEn.push(obj);
const uniqueArr = uniqueArray(state.languageGatherEn)
localStorage.setItem('languageGatherEn', JSON.stringify(uniqueArr))
uniqueArr.forEach(item => {
i18n.mergeLocaleMessage('en', item)
});
console.log('国际化的英文数据='+i18n.messages.en);
},
}
getters = {
languageGatherZh: state => state.common.languageGatherZh,
languageGatherEn: state => state.common.languageGatherEn,
}
去重方法:
/**
* 数组嵌套多层对象根据嵌套对象的键去重
* @param array 数组名
*/
export const uniqueArray = (arr) => {
return arr.reduce((acc, current) => {
const found = acc.find((item) => JSON.stringify(item) === JSON.stringify(current));
if (!found) {
acc.push(current);
}
return acc;
}, [])
};
后台请求数据:
getList().then(res => {
res.data.data.forEach(item => {
/* 获取建筑物下拉数据 */
if (item.code == "buildLocation") {
let objectLocation = {};
let objectLocationEn = {};
item.children.forEach(_item => {
objectLocation[_item.code] = _item.name;
objectLocationEn[_item.code] = _item.code;
this.positionOptions.push({
label: _item.code,
value: _item.id,
riskValue: _item.value
})
})
this.$store.commit("SET_LANGUAGE_ZH", {
buildLocation: objectLocation
});
this.$store.commit("SET_LANGUAGE_EN", {
buildLocation: objectLocationEn
});
}
})
})
因为示例做的是下拉数据:所以一定要注意value和label的值:
<el-form-item label="$t(obj.position)">
<el-select filterable clearable v-model="formBudding.position" @change="changeCd">
<el-option v-for="(item, index) in positionOptions" :key="index"
:label="$t(`buildLocation.${item.label}`)" :value="item.value">
</el-option>
</el-select>
<span style="margin-left: 15px;color: #909399;">{{ cdRisk }}</span>
</el-form-item>