使用vue-i18n进行项目国际化

vue-i18n方案文档

简介

安装

npm i -S vue-i18n

配置

cd project-path/src/***
mkdir i18n
cd i18n
touch index.js
mkdir lang
touch zh-CN.js en-US.js

1.zh-CN.js和en-US.js为具体语言包;

2.index.js负责实例化VueI18n ,加载应用语言包,export出i18n;

3.项目入口文件在实例化Vue时引入i18n:const app = new Vue({router, i18n, ...})

语言切换

// ./i18n/index.js
// 按需加载(此实现需要lang与语言包js文件同名,如'zh-CN'、'us-EN'等)
export function loadLanguageAsync (lang) {
  if (i18n.locale !== lang) {
    if (!loadedLanguages.includes(lang)) {
      return import(`./lang/${lang}`).then(msgs => {
        i18n.setLocaleMessage(lang, msgs.default[lang]);
        i18n.setDateTimeFormat(lang, msgs.default[lang]);
        i18n.setNumberFormat(lang, msgs.default[lang]);
        loadedLanguages.push(lang);
        return setI18nLanguage(lang);
      });
    };
    return Promise.resolve(setI18nLanguage(lang));
  }
  return Promise.resolve(lang);
}
// 设置语言包
function setI18nLanguage (lang) {
  i18n.locale = lang;
  return lang
}

// ***.vue
import { loadLanguageAsync } from '../i18n'
export default {
    methods: {
        chooseLanguage(lang) {
            localStorage.setItem('lang', lang);
            loadLanguageAsync(lang)
      }
    }
}

使用

// ./i18n/lang/zh-CN.js
const cn = {
    staff: {
        meta: {
            name: '姓名'
        }
    }
}
export default {
    'zh-CN': cn
}
// ./i18n/lang/en-US.js
const en = {
    staff: {
        meta: {
            name: 'Name'
        }
    }
}
export default {
    'en-US': en
}

// ./i18n/index.js
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import langs from './lang/cn'
//默认加载中文
export const i18n = new VueI18n({
  locale: 'cn',
  messages: langs,
  numberFormats: langs,
  dateTimeFormats: langs
})

// main.js or index.js (项目入口文件)
import { i18n } from '$client/i18n';
new Vue({
  router,
  i18n,
  render: h => h(App)
}).$mount('#app');

// ***.vue
<span>{{ $t('staff.meta.name') }}</span>

常用方法

$t(path, locale, option) // text 文本替换,locale可单独设置语言,option可传参数替换模板
$tc(path, choice, locale, option) // text+choice 比$t多一个choice,可以选择模板内容(模板内容间用 | 分隔,如 香蕉|苹果|梨,最多只能使用三个选项,下标从0开始,当选项为2个时下标从1开始~~)
$te(path) // text+exist 判断当前语言包中path是否存在
$d(number|Date, path, locale) // date 时间格式化
$n(number, path, locale) // number  数字格式化(货币等)

// 更多细节参考官方文档:https://kazupon.github.io/vue-i18n/api/#vue-injected-methods

问题记录

语言包规范

/*
* 语言包主要分为三部分:
*   1.constant:项目内置的常量等;
*   2.customized:为了UI展示自定义内容
*   3.如element-ui内置的zh-CN等额外的语言包
* export时将各部分进行合并,隐藏细节以便使用
*/

// 以zh-CN.js为例
import merge from 'deepmerge'
import cnLocale from 'element-ui/lib/locale/lang/zh-CN';

const constant = {
    staff: {
        gender: {
          0: '保密',
          1: '男',
          2: '女'
        },
        // ...
    },
    account: {
        // ...
    },
    // ...
}
const customized = {
    staff: {
        state: {
          all: '全部'
        },
        meta: {
          name: '姓名',
          sector: '所在分支',
          phone: '手机号',
          state: '状态',
          operation: '操作'
        },
        // ...
    },
    account: {
        // ...
    },
    // ...
}
export default {
  'zh-CN': merge.all([constant, customized, cnLocale])
};

项目集成i18n工作量

  1. 涉及文案需要变化展示的代码都需要改,人工工程量较大。
  2. 语言包中key和value需要产品经理进行更合理的语义翻译。

待解决问题

  1. 内部封装库的(假设名字为comman-components)国际化方案如何实施?

    • 方案一:制作comman-components专用的语言包,业务层引入biz-packages时需要在对应语言包中导入comman-components的语言包,合并后导出。

      举例:如在comman-components中创建lang文件夹,里面做了一个中文包为cn.js,业务层中的zh-CN.js就可以import bizCnLocale from './comman-components/src/lang/cn',在最后export default {'zh-CN': merge.all([constant, customized, bizCnLocale ])},这样comman-components的语言包就可以生效了。

      业务层必须使用i18n,否则显示会出问题

    • 方案二:借鉴element-ui,制作comman-components专用的locale、lang、mixins,对外暴露接口。

      element-ui有完整的流程可供参考,此方案比较安全,业务层没有使用i18n时可以有默认语言,但逻辑复杂,工程量较大。

      业务层不强制使用i18n,但逻辑较为复杂

    • 方案三:在业务层把语言包做成一大个,其他业务要用的时候自己加上(类似方案一,但没有独立为文件,语言需要去公共空间拷贝)。

      临时方案,目前可用,但非长久之计

      业务层必须使用i18n,否则显示会出问题

  2. 服务端如何更好的配合国际化工作?
  3. 如果整个项目的同语言的语言包都放在一个文件中,文件体积是否过大且无必要?

猜你喜欢

转载自blog.csdn.net/qq_39300332/article/details/82557438