历史搜索

Vue国际化 i18n 项目一点想法

游客2024-10-03 12:33:02
目录文章目录
  1. 前言
  2. 国际化是什么?
  3. 实现基本国际化功能
  4. 优化 i18n 配置
  5. 结语

前言

如果你的项目是 Vue,那么相信你在实现国际化功能时,也必不可少的会使用到 vue-i18n 这个库,接下来本文也是通过这个库搭配 Vue 实现最基本的国际化功能,但关注点并不是如何使用这个库,而是在实现的过程中思考 可优化的点。好了,废话不多说,开干。

国际化是什么?

国际化 对应的英文单词为 Internationalization,又称 i18n

  • i 为单词的 【第一个】 字母
  • 18 为 【in之间】 单词的个数
  • n 代表这个单词的 【最后一个】 字母

实现基本国际化功能

本文就不再多余演示 demo 项目的创建过程了,并且文中只演示最基本的 中英文 切换,好了现在直奔核心吧!

集成 vue-i18n

安装依赖

熟悉的命令:

npm install vue-i18n -S

配置 vue-i18n

1. 在 src 目录下创建 language 目录用于保持和语言切换相关的内容

2. 在 language 目录下创建 lang 目录用于保存不同语言的映射关系,如中文对应 zh.js、英文对应 en.js 等Vue国际化 i18n 项目一点想法 1

升级为 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 的响应式来切换翻译内容的,即不会刷新页面,因此在切换对应翻译内容后,同样需要修改后续接口请求头中的语言环境。

但这样还是有问题的,已经通过接口返回的数据内容,此时没有办法切换成对应的翻译内容,因为当前的国际化切换是基于页面的变动,但基于接口变动的部分还没重新请求获取新的内容,那怎么处理呢?

  • 前端切换语言环境后,重新刷新页面,让接口也重新获取新的内容;
  • 后端在返回数据时,将对应的不同语言环境的翻译内容一起返回,由前端根据语言环境决定如何渲染;
  • 将所有的翻译内容全部交由前端管理,一开始就初始化好各个语言环境对应的翻译内容。

结语

以上内容是基于国际化功能的一点思考,文中对应的思考点是笔者自己在项目中遇到的点,并不一定适合所有项目,当然也期待评论区给出更多、更好的方案。