[Vue] 跟着 Vue 闯荡前端世界

要让网站也可以提供给外籍人士使用,不可免俗的需要多国语系的支持,因此本文透过 vue-i18n 来打造一个多国语系网站,并介绍基本的使用情境及用法。


实践方式


首先安装套件,并且建立 i18n.js 文件来产生 VueI18n 对象实例。

npm install vue-i18n --save

import Vue from 'vue'
import VueI18n from 'vue-i18n'

// 自订语言档
import en from '../i18n/en/lang'
import tw from '../i18n/tw/lang'

// 使用插件
Vue.use(VueI18n)

// 取得默认语系
const locale = localStorage.getItem('locale') || 'tw'

// 建立 VueI18n 实例
const i18n = new VueI18n({
  locale,
  messages: { en, tw }
})

export default i18n

中英文语言档如下

/* /tw/lang.js */
export default {
  __ok: '好',
  __continue: '继续',
  __cancel: '取消',
  __guest: '访客'
}
/* /en/lang.js */
export default {
  __ok: 'ok',
  __continue: 'contiune',
  __cancel: 'cancel',
  __guest: 'guest'
}

语言档设计要点


1. 使用特殊前缀符号

由于项目通常都是多人开发,因此绝对会发生两个相同“文字”重复被建立,而这情况往往会在最后总整理的时候才会被发现,此时可以使用具有特殊前缀符号的 key 来查询取代,降低误查到其他不相关代码的几率。

2. 仅针对中文先处理

翻译这种东西通常会交给专业的来处理,所以开发人员去填个假的也没什么意义,因此干脆就不要花时间处理了;此时不必担心网页切换到英文会呈现一片空白,因为当找不到对应语言档时会直接呈现所设定的 key 值,同时还可以借此了解那些文字尚未被纳入多国语系处理范围喔!

3. 依照文字意义命名

真的不需要依照页面或功能作为 key 命名,除非是一整段功能说明文字可以考虑使用类似 xxFuncNote 的命名;因为实际使用上多透过“文字”去寻找“key”值来套用,所以笔者建议不需要在 key 值的命名多加着墨,只要尽量减短并贴近语义让 key 尽量内含一些意义存在即可。

4. 使用单一文件即可

笔者在开发初期有尝试依照共用、页面或组件来区分语言档,不过在多人开发环境之下,其实很难区分文字是属于哪种类型,因此一定会出现许多相同文字的翻译档散落四处;另外,要如何将分散四处的翻译档交给专业的人来处理也是个大问题,因此笔者最终还是回归到单一语言档,而这样的好处就是 key 值永远不会重复(IDE会帮忙检查),最终在整理语系文字的时候也只要 sort by 文字就可以理出是否有重复定义的文字,并且在交付翻译人员的处理上也方便。

套用语系


会使用到语系的地方约略区分三种,组件 tempate 区块、组件 script 区块以及任何 js 文件中,在组件中可以使用 $t(__key) 方法操作,范例请参考以下各区使用方式。

组件 tempate 区块 

组件 script 区块

在任何 js 文件中

切换语系


直接 import 先前所建立的 VueI18n 实例,设定 locale 值后随即进行切换。

import i18n from 'i18n '

/
 * @description 切换网站语系
 */
const switchLang = (newLang) => {
  i18n.locale = newLang
  localStorage.setItem('locale', newLang)
}


switchLang('tw') // 切换至中文
switchLang('en') // 切换至英文

特殊用法


多国语系不仅仅只是作为一对一翻译的资源档而已,由于英文会因单复数而产生不一样的单字,另外各语系的语法顺序皆不尽相同,所以 vue-i18n 提供了许多便捷的处理方式,以下参考。

插入参数

可以在语系文字中插入参数 (ex. 欢迎 XXX 加入开发团队),官方范例如下:

lang.js

template in *.vue

result

也可以在语系定义档中使用 {0} 作为标示,调用端就使用数组依序传入参数值喔!

单复数处理

可以针对英文两(三)种单复数型式 (零、单、复数) 做语系文字的对应,官方范例如下:

lang.js

template in *.vue

result

注意要套用单复数功能要改用 $tc 这个方法喔!

动态修正语系文字


语系档通常都会与网站放在同一包,如果要改文字就需要重新打包上板,但有一些情况是必须立即修正文字的,所以如果只是为了改个几个字就要重新包版上板也是满不符合经济效益的,更何况若网站是透过 cordova 包装成 app 时更是繁琐,因此我们可以透过 API 的叫用,取得需要调整的语系文字 (key, twValue, enValue) 来覆写目前默认的文字,这样的弹性又更好了,请参考以下作法。

// app.vue

import tw from 'i18n/tw/lang' // 存放繁体翻译
import en from 'i18n/en/lang' // 存放英文翻译

export default {
  name: 'App',
  mounted () {

    // 透过 API 更新语系档文字 (hotfix)
    this.updateModifiedLangs()

  },
  methods: {

    // 更新语系 [非"常态"行为,仅供紧急性质的语文修正]
    updateModifiedLangs: async function () {
      const res = await this.$api.common.getModifiedLangs()
      const {header: { code }, body: modifiedLangs} = res
      if (code.IsSuccess() && modifiedLangs) {
        modifiedLangs.forEach(lang => {
          tw[lang.key] = lang.tw
          en[lang.key] = lang.en
        })
      }
    }
}
紧急修正的文字最终需要回归到本地端的语系文件中喔! (避免两份文档难以维护)

语系查询工具


开发过程中套用多国语系是非常花时间的事情,尤其若是要自己去一堆语系档中找寻是否已有定义过的文字是非常考验耐性的工作,因此笔者为减轻自己及开发团队的负担而开发了小工具,诉求如下。

  1. 依据关键字自动查询已存在的语系文字 (包含即列入显示清单)
  2. 自动选择相同的语系文字并产出语法
  3. 有按钮可以自动复制语法 (省去鼠标圈选时间)
  4. 若不存在可以透过界面建立新语系文字并产出语法
  5. 新建的语系文字可记录起来累积到一定的量在贴回语系档中

操作方式如下

源代码如下,有相同困扰的朋友可以参考一下








参考资讯


vue-i18n v6.0+ Doc


希望此篇文章可以帮助到需要的人

若内容有误或有其他建议请不吝留言给笔者喔 !