前言
如果你的项目是 Vue
,那么相信你在实现国际化功能时,也必不可少的会使用到 vue-i18n 这个库,接下来本文也是通过这个库搭配 Vue
实现最基本的国际化功能,但关注点并不是如何使用这个库,而是在实现的过程中思考 可优化的点。好了,废话不多说,开干。
国际化是什么?
国际化 对应的英文单词为 Internationalization,又称 i18n
:
i
为单词的 【第一个】 字母18
为 【i
和n
之间】 单词的个数n
代表这个单词的 【最后一个】 字母
实现基本国际化功能
本文就不再多余演示 demo
项目的创建过程了,并且文中只演示最基本的 中英文 切换,好了现在直奔核心吧!
集成 vue-i18n
安装依赖
熟悉的命令:
npm install vue-i18n -S
配置 vue-i18n
1. 在 src
目录下创建 language
目录用于保持和语言切换相关的内容
2. 在 language
目录下创建 lang
目录用于保存不同语言的映射关系,如中文对应 zh.js
、英文对应 en.js
等
升级为 i18n 系统
上面已经将对应的翻译包从 *.xlsx
转成了 *.json
的形式,这样一定程度上能减少重复劳动力,但在 复用/协作 方面还是不够理想,因此可以从更高的维度将这整个内容升级到 i18n
系统,并提供对应的翻译包上传、自动解析、去重、添加命名空间等功能,再加上对应的列表管理功能,重点是可供多人员、多系统进行 复用/协作,对前端来讲就可以通过 接口 获取对应的翻译包数据,也能减少前端最终构建产物的体积。
处理翻译文件中重复的内容
什么叫重复的内容呢?其实很简单,比如有个文字内容为 确认 按钮,它在 A
页面需要翻译为 Confirm
,它在 B
页面需要翻译为 OK
,而它的中文内容就是 确认
,意味着它对应的数据内容为:
[ { "Short": "确认", "Chinese": "确认", "English": "Confirm" }, { "Short": "确认", "Chinese": "确认", "English": "OK" } ]
但这样其实是不行的,这样最终会被后面的内容覆盖掉,即 A、B
页面最终的翻译内容都为 OK
,因为数据中的 Short
其实就是最终的不同语言映射的 key
,如下:
const messages = { zh: { "确认": "确认", "确认": "确认" }, en: { "确认": "Confirm", "确认": "OK" } };
既然这样,那么其实我们只要为不同的翻译内容设置不同的 Short
值即可,如下:
[ { "Short": "确认 1", "Chinese": "确认", "English": "Confirm" }, { "Short": "确认 2", "Chinese": "确认", "English": "OK" } ]
这样变动小,并且也没有丢失掉原本的语义。
考虑不同语言的样式
由于不同语言的表现形式不同,内容长度也不一致,因此在前端进行展示时,就必须要考虑到最终的显式问题,否则一旦切换语言环境那么一定会导致页面的布局展示出现问题,处理方式无非几种:
- 允许文字内容换行展示,在文字发生换行时,要通过
CSS
设置按完整词换行 - 不允许换行的,就要控制固定宽度,超出部分打点展示,鼠标移入展示全部内容等
- 单独为不同语言环境设置样式,具体还是得看展示需求,如需要考虑不同语言环境下文字的对齐方式、文字间距等
- 针对难以处理的翻译内容,可以通过和业务沟通是否可以替换翻译内容、缩减文字长度等等
考虑后端接口语言环境变更
一个项目的国际化不可能都是前端来实现的,一些接口动态返回的内容也是需要后端去处理的,通常接口的请求头中会存储一个用于标识当前页面语言环境的字段,然后再决定返回给前端页面的具体内容。
基于前面处理的国家化切换功能,本身是会基于 vue
的响应式来切换翻译内容的,即不会刷新页面,因此在切换对应翻译内容后,同样需要修改后续接口请求头中的语言环境。
但这样还是有问题的,已经通过接口返回的数据内容,此时没有办法切换成对应的翻译内容,因为当前的国际化切换是基于页面的变动,但基于接口变动的部分还没重新请求获取新的内容,那怎么处理呢?
- 前端切换语言环境后,重新刷新页面,让接口也重新获取新的内容;
- 后端在返回数据时,将对应的不同语言环境的翻译内容一起返回,由前端根据语言环境决定如何渲染;
- 将所有的翻译内容全部交由前端管理,一开始就初始化好各个语言环境对应的翻译内容。
结语
以上内容是基于国际化功能的一点思考,文中对应的思考点是笔者自己在项目中遇到的点,并不一定适合所有项目,当然也期待评论区给出更多、更好的方案。