给Vue组件加上国际化支持

起源

由于产品诉求,需要给已有发布的组件添加国际化支持功能,网上大部分都是国际化插件使用的案例,所以经过了一番摸索实践,有了一下的方案。我这里使用的插件是 vue-i18n,借鉴(抄了)了element-ui中的国际化部分源码。

关键源码

在组件目录中添加 locale 文件夹,目录结构如下:

locale
 ├── index.js          # 核心文件
 ├── locale.js         # 混入文件
 └── lang              # 多语言
      ├── en-US.js     # 英文
      ├── zh-CN.js     # 简体
      └── zh-TW.js     # 繁体

index.js 源码:

import defaultLang from './lang/zh-CN'
let lang = defaultLang
let i18nHandler = function () {
  const vuei18n = Object.getPrototypeOf(this).$t
  if (typeof vuei18n === 'function') {
    return vuei18n.apply(this, arguments)
  }
}
export const t = function (path, options) {
  let value = i18nHandler.apply(this, arguments)
  if (value !== null && typeof value !== 'undefined') {
    return value
  }
  const array = path.split('.')
  let current = lang
  for (let i = 0, j = array.length; i < j; i++) {
    const property = array[i]
    value = current[property]
    if (i === j - 1) return value
    if (!value) return ''
    current = value
  }
  return ''
}
export const use = function (l) {
  lang = l || lang
}
export const i18n = function (fn) {
  i18nHandler = fn || i18nHandler
}
export default {use, t, i18n}

i18nHandler 是用来检测并套用 vue-i18n 的,如果用户安装了这个插件,则会使用绑定在 Vue 实例上的 $t 方法进行取值。首先看能否用 i18nHandler 取到,如果能取到则直接用,取不到就要自行解决了。最后返回取到(或者取不到,则为空)的值。
usei18n 这两个方法是在整个组件库作为插件被 Vue 安装的时候调用的,主要用来让用户自定义语言。

locale.js 源码:

import { t } from '../locale'

export default {
  methods: {
    t (...args) {
      return t.apply(this, args)
    }
  }
}

通过混入给组件加上一个 t 方法。组件在需要根据语言切换的地方,只要加入这个 mixin 并在输出的地方使用 t(key) 即可。

语言包源码:

// zh-CN.js
export default {
    public: {
        placeholder: '请输入',
        login: '登录',
    }
};

// zh-TW.js
export default {
    public: {
        placeholder: '請輸入',
        login: '登入'
    }
};

// en-US.js
export default {
    public: {
        placeholder: 'Place enter ',
        login: 'Login'
    }
};

将上述的两个方法 use 和 i18n 写入到组件库入口的 install 方法中去:

import locale from '../locale';
const install = function (Vue, opts = {}) {
    locale.use(opts.locale);
    locale.i18n(opts.i18n);
};

组件中调用

在需要调用的组件中混入 locale.js

<template>
    <div>
        {{ t('public.login') }}
        <input v-model="value" :placeholder="t('public.placeholder')">
    </div>
</template>
<script>
    import Locale from '../../locale/locale.js';
    export default {
        mixins: [Locale],
        data() {
            return {
                value: ''
            }
        }
    }
</script>

最后

别忘了在组件的 package.json 中把 locale 文件输出:

"files": [
    "lib",
    "locale"
],

这样一个支持国际化语言的组件就基本完成。

使用

基本用法和 element-ui 用法一致,这不废话吗,就是借鉴(抄的)人家的源码……

之前还有一篇是介绍《Vue国际化配置》,也可以同样参考。

已有 2 条评论

  1. 回复

    你写得非常清晰明了,让我很容易理解你的观点。

  2. 回复

    这个代码我先留存起

添加新评论