chrome浏览器扩展国际化那些事
背景
最近在为浏览器插件《油管评论翻译机》迭代,涉及到国际化(切换国家语种),记录一下。
技术选型:vue+element-ui+chrome扩展+i18n+Express
实现过程
本扩展涉及到国际化的地方有:弹窗页(page_action:default_popup)、选项页(options_page或options_ui:page)、注入页(content_scripts)、chrome扩展管理页、后端接口。
如果项目中没有手动切换语种的要求,那直接使用chrome扩展的chrome.i18n.getMessage('name')轻松实现国际化。反之,就需要多想点办法了。我总结为以下三种方式。
一、使用vue+element-ui+vue-i18n实现国际化
这和chrome扩展没依赖关系,是element-ui官方推荐的国际化方案。具体实现参考官方文档(element-ui国际化文档),如果不是很清楚,推荐看这两篇文章: 《vue+elementUI+vue-i18n 实现国际化》、 《vue实现多语言国际化(vue-i18n),结合element ui、vue-router、echarts以及joint等》。
其中有几点值得提一下:
1. 数据结构不同
element-ui
定义的数据结构和chrome扩展的不同。
以下是element-ui
的locale文件,取自element-ui/lib/locale/lang/zh-CN.js
exports.default = {
el: {
colorpicker: {
confirm: '确定',
clear: '清空'
},
datepicker: {
now: '此刻',
today: '今天',
}
...
}
以下是chrome扩展要求的结构,取自_locales/zh_CN/messages.json (该文件需自建,后面细说)
{
"name": {
"message": "油管评论翻译机",
"description":""
},
"desc": {
"message": "一款轻松翻译YouTube评论的浏览器扩展,支持多国语言、双语对照、评论导出、样式修改等。",
"description":""
}
}
看出区别了吗? chrome扩展有固定的格式,不一致会导致获取失败,所以需要按chrome的格式来写,再转化结构来供element-ui使用,当然你也可以分开做两份。
2.定义默认语言
element-ui定义默认语言可通过上面提到的vue-i18n
来实现,即:
const i18n = new VueI18n({
locale: 'zh_CN', //默认中文(简)
...
})
3.切换语言
在vue下拉菜单中切换,直接更改this.$i18n.locale的值即可。
changeLanguage(lang) {
this.$i18n.locale = lang
}
4.渲染
在vue模板中,直接使用$t调用:
<span>{{$t('name')}}</span>
同理,在vue js中使用:
const name = this.$t('name')
二、chrome扩展自身国际化
上文介绍的都是vue能控制的范围,但像下面这种,以及在注入页(content_scripts), 后台运行页(background)等,就需要chrome扩展自带的国际化方法来实现。
具体实现方式参考360翻译的官方文档《chrome扩展国际化》,以及民间文章《Chrome插件i18n多语言实现》,讲得非常详细。
总结起来就是:
1. 定义语种
如果manifest.json里配置了default_locale属性,chrome就会去根目录寻找_locale下对应的语种,比如中文简体为:_locale/zh_CN/messages.json,具体格式上面有简单提到。
chrome扩展支持的所有语种:am ar bg bn ca cs da de el en en_GB en_US es es_419 et fi fil fr gu he hi hr hu id it ja kn ko ltlv ml mr nl or pl pt pt_BR pt_PT ro ru sk sl sr sv sw ta te th tr uk vi zh zh_CN zh_TW。
2. 调用
① 在js中调用
chrome.i18n.getMessage('name')
这里的getMessage还支持第2个参数,用于占位,可带入变量。用法如下:
//messages.json定义
{
"hello": {
"message": "你好, $USER$",
"placeholders": {
"user": {
"content": "$1",
"example": "李四"
}
}
}
}
//js调用
const msg = chrome.i18n.getMessage('hello','张三')
② 在manifest.json或css中调用
使用字符变量__MSG_xxxx__
,或调用方法getMessage("_xxxx_")
:
//manifest.json:
{
"name": "__MSG_name__",
"description": "__MSG_desc__",
"default_locale" : "zh_CN",
"manifest_version": 2,
...
}
// css:
#app{
width: __MSG_width__;
}
写到这里出现一个问题,如果你使用chrome.i18n.getMessage,用户想切换语言,除了在浏览器设置语种后重启,暂时还没发现热切换的方法。我的做法是除非必要,尽量避免使用chrome.i18n.getMessage,通过vue+element-ui那套方式来实现,并把选中的语种保存在缓存中,还可供后端接口调用,这就引出了下面这种场景。
三、后端接口国际化
前端可把语种封装到headers统一传给后端,就像这样:
// 前端 axios
const locale = 'zh_CN';
axios.interceptors.request.use(
config => {
config.headers.locale = locale; //和后端约定一个属性
return config
}
...
)
//后端 Express
const getInfo = async (req, res, next) => {
let { locale } = req.headers;
...
}
后端已拿到语种,国际化就好办了,已超出前端范畴,略。
总结
浏览器扩展是个好东西,能大大提高生产力。目前我也只写过两个扩展,一个是《油管评论翻译机》,另一个是几年前写的《基金助手》,每次写都能发现新大陆,建议大家亲手试试。
热门文章
- 微信小程序“拍照识图”上线(63,758)
- YouTube评论翻译插件《油管评论翻译机》上线了(60,288)
- 基金助手--chrome浏览器插件(45,192)
- 拍照识别彩票结果在线工具(31,943)
- vue+tabs动态组件方案漫谈(26,476)
- 《油管评论翻译机》使用说明书(25,337)
- 网页打印插件Print.js(23,978)
- 自用YouTube抓取评论+翻译工具(23,380)
- YouTube评论导出免费在线工具(18,053)
- px转rem/vw方法小结(17,565)