vue多语言的解决方案不只是 vue-i18n,前端+后端完整解决方案
vue多语言的解决方案不只是 vue-i18n,前端+后端完整解决方案
网上搜很多vue多语言的,一般都是介绍vue-i18n怎么使用,当然这是不错的,但是我们如果只是讲这个的话,只是解决了静态文字的多语言化。
这一部分我们也简单讲一下
npm install vue-i18n --save
安装
// main.js
import VueI18n from 'vue-i18n';
import messages from './i18n';
Vue.use(VueI18n);
const locale = (localStorage.getItem("language") || navigator.language || navigator.browserLanguage).toLowerCase();
为了避免被坑都转成小写。
// 通过选项创建 VueI18n 实例
const i18n = new VueI18n({
locale, // 设置地区
messages, // 设置地区信息
});
new Vue({
router,
store,
i18n,
render: (h) => h(App),
}).$mount('#app');
里面的messages
就是我们的多语言数据
//i18n/index.js
export default {
['zh-cn']: {
hello: '你好',
},
['en-us']: {
hello: 'Hello',
}
}
这里的zh-cn
是和上面的zh-cn
对应的.
在.vue文件里面使用时就是这样
<tempalate>
<div>
{{$t('hello')}}
</div>
</tempalate>
到这里vue-i18n
说完了
很多时候我们在处理接口返回、录入的数据也需要支持多语言的。比如电商运营人员是需要提前分别输入商品的中文名和英文名的。 否则会出现这样的(这是一个录入电商运营人员录入品牌信息的页面)
是不是多少有点怪啊。 我们是不是需要这种 录入英文
录入中文
前端怎么实现的? 在没有多语言的情况下,表单绑定的数据是这样的
dataForm = {
brandName: '',
sort: 0,
isDisplay: 1,
}
显然这里的品牌名brandName
是需要支持的多语言的,其它的都是数字也不涉及到什么多语言。
我们需要改造下dataForm
dataForm = {
brandName: {
['en-US']: '',
['zh-CN']: ''
},
sort: 0,
isDisplay: 1,
}
此时dataForm.brandName
不再是字符串了,而是对象了,这样我们就根据key的变化显示对应的值,这样brandName
能使用多语言了。
实际使用过程中跟上面的例子还是略有不同的
- 某个用户支持哪些语言,提前是不知道的,需要有一个单独提供支持语言的接口返回的,所以我们无法简单的像
brandName: {['en-US']: '',['zh-CN']: ''},
这样写死的。 - 历史数据怎么处理?历史数据都是不支持多语言的啊,总不能自行判断,然后有的
brandName
是字符串,有的是对象吧,想想都不好处理。如果所有的数据都是统一格式不就好了?这时很自然的想到了数据的归一化。可以参考我昨天写的《从mapState、mapMutations的源码看数据归一化normalize》
首先我们要支持一点,既然开始支持多语言了,那就需要用户指定一个默认语言,历史数据就是那个默认语言的数据。
以上面的例子的后端返回数据为例继续讲。
后端肯定不会再原始表里面加字段,比如en-US-brandName
之类的。他们会建立一个多语言的表,专门存储多语言信息,在原始表里面还是存储默认语言信息。
这样如果数据已经存在多语言的会返回这样,默认语言为中文zh-CN
data: {
brandName: '品牌XX',
sort:2,
isDisplay: 1,
langMap: {
'zh-CN': {
brandName: '品牌XX',
},
'en-US: {
brandName: 'brandXX',
}
}
}
外层的brandName
的值就是该用户的默认语言的值,这样也是为了兼容性考虑的。
历史数据(也就是前端没有提交过多语言信息的)
data: {
brandName: '品牌XX',
sort:2,
isDisplay: 1,
}
其实你是多么希望就算原来没有多语言,后端也会这样返回
data: {
brandName: '品牌XX',
sort:2,
isDisplay: 1,
langMap: {
'zh-CN': {
brandName: '品牌XX',
},
}
}
哈哈,每一个强大的前端都是被产品、后端、设计师、测试逼出来的。
前端就要这么强。
我们可以根据接口拿到数据后,自己判断是否有langMap
,如果没有,我们就直接将数据归一化变成含有langMap
的。
然后我们需要根据langMap
再次处理数据,最终变成
data(){
return {
dataForm = {
brandName: {
['en-US']: 'brandXX',
['zh-CN']: '品牌XX'
},
sort: 0,
isDisplay: 1,
},
languageList:[{
languageCode: 'zh-CN',
language: '简体中文'
},{
languageCode: 'en-US',
language: 'Englist'
}]
};
},
<template>
<section>
<el-radio-group
class="lang-select"
:value="currentLang"
size="small"
>
<el-radio-button
v-for="(item, index) in languageList"
:key="'lang' + index"
:class="currentLang === item.languageCode ? 'active' : ''"
:label="item.languageCode"
@click.native="currentLang = item.languageCode"
>
{{ item.language }}
</el-radio-button>
</el-radio-group>
<el-form :model="dataForm">
<el-form-item :label="$t('brand_name')" prop="brandName">
<el-input
v-model.trim="(dataForm.brandName || {})[currentLang]"
maxlength="50"
></el-input>
</el-form-item>
<el-form-item :label="$t('sort')" prop="sort">
<el-input
v-model.trim="dataForm.sort"
></el-input>
</el-form-item>
<el-form-item
:label="$t('display_is_or_no')"
prop="isDisplay"
>
<el-radio-group v-model="dataForm.isDisplay">
<el-radio :label="1">{{ $t("yes") }}</el-radio>
<el-radio :label="0">{{ $t(no") }}</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</section>
</template>
这里的上半部分就是多语言选择器那一部分了,通过点击切换当前语言currentLang
,下面的v-model.trim="(dataForm.brandName || {})[currentLang]"
这里的品牌名的值也就会切换对应的key显示对应的文字了。
- 分类:
- Web前端
相关文章
用在线IDE写vue代码
上周末无意中发现了一个新的在线IDE,网址glitch.com,个人感觉很不错,于是顺便关注了下其它的在线IDE,比如codesandbox.io也不错,没有细看,可能自己已经先入为主的喜欢上glit 阅读更多…
Vue2.6.10源码分析(一)vue项目怎么神奇的跑起来的
先看index.html的代码吧 <!DOCTYPE html> <html lang="en"> <head> <meta 阅读更多…
element-ui表单源码解析之el-input
关于表单校验el-input做的主要工作就是跟el-form-item交互,把input的相关事件发送给el-form-item,上一篇已经讲到在el-form-item的mounted的生命周期里 阅读更多…
React router用hooks读取routeName、根据routeName跳转
在迁移Vue至React的过程中遇到了一些路由相关的问题,在Vue项目中经常会使用routeName,毕竟使用path太长了,也记不住,我自己看了看React router也没有发现routeNam 阅读更多…
命令式组件Message、Dialog的主流写法分析
这里还是以element-ui为例,那我们就看看里面的Message。 它的dom结构什么的就写在node-modules/element-ui/packages/notification/src/ 阅读更多…
vue实现自定义组件的v-model双向数据绑定
一般来说我们用v-model是在input中 常见用法如下 <input type="text" v-model="username"> 用户名:{{username}} 其 阅读更多…