IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    给Vue组件加上国际化支持

    王叨叨发表于 2023-03-29 17:21:00
    love 0

    起源

    由于产品诉求,需要给已有发布的组件添加国际化支持功能,网上大部分都是国际化插件使用的案例,所以经过了一番摸索实践,有了一下的方案。我这里使用的插件是 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 取到,如果能取到则直接用,取不到就要自行解决了。最后返回取到(或者取不到,则为空)的值。
    use 与 i18n 这两个方法是在整个组件库作为插件被 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国际化配置》,也可以同样参考。



沪ICP备19023445号-2号
友情链接