记录使用vue-i18n实现项目的双语国际化

前言

本文是使用vue2.x + ant-design-vue 搭建的项目,对于框架使用不会做过多的说明

以下是需要思考的问题

1、如何使用vue-i18n ?

2、翻译的字段数据存放在哪里合适 ?

3、ant-design-vue如何国际化 ?

4、如何全局监听切换了语言 ?

5、语言的不同如何兼容样式 ?

使用vue-i18n

1. 安装  注意:vue2.x要安装第8版本,vue3.x安装第9版本

npm install vue-i18n@8

2. 引入 + 挂载 + 使用

我这边是新建了个plugin/vuei18n文件夹去管理该插件的内容

// vuei18n/index.js

import Vue from 'vue'
import Vuei18n from 'vue-i18n'

Vue.use(Vuei18n)

很多人在将翻译的字段都是放在本地由前端去维护,这里我推荐是在后台系统有个地方专门管理语言互译的字典管理的,这样做的好处哪怕以后翻译的文案不正确直接在后台修改即可,不需要前端修改后又要重新发版上线

// vuei18n/index.js
// 模拟从后台获取中英互译数据
/*
假设数据结构
{
  dictType: "common", // 分类
  dictLabel: "user", // 描述
  dictZhValue: "大栗子", // 中文值
  dictEnValue: "lily" // 英文值
}
*/
const i18nData = () => {
  return [{
    dictType: 'link',
    dictLabel: 'homeLink',
    dictZhValue: '首页',
    dictEnValue: 'Home'
  }, {
    dictType: 'link',
    dictLabel: 'detailLink',
    dictZhValue: '详情',
    dictEnValue: 'Detail'
  }, {
    dictType: 'home',
    dictLabel: 'username',
    dictZhValue: '姓名',
    dictEnValue: 'username'
  }, {
    dictType: 'home',
    dictLabel: 'password',
    dictZhValue: '密码',
    dictEnValue: 'password'
  }, {
    dictType: 'home',
    dictLabel: 'email',
    dictZhValue: '邮箱',
    dictEnValue: 'email'
  }, {
    dictType: 'detail',
    dictLabel: 'desc',
    dictZhValue: '这是详情页',
    dictEnValue: 'This is a detail page'
  }]
}

const geti18nData = () => {
  const res = i18nData()
  const zh = {} // 存储中文
  const en = {} // 存储英文
  for (const item of res) {
    if (!zh[item.dictType]) {
      zh[item.dictType] = {}
      en[item.dictType] = {}
    }
    zh[item.dictType][item.dictLabel] = item.dictZhValue // 中文
    en[item.dictType][item.dictLabel] = item.dictEnValue // 英文
  }
  return {
    zh,
    en
  }
}

打印的结果

 3. 初始化i18n

// vuei18n/index.js
const initVuei18n = () => {
  const { zh, en } = geti18nData()
  return new Vuei18n({
    locale: 'zh-CN', // 默认为中文
    messages: {
      'zh-CN': zh,
      'en-US': en
    }
  })
}

const i18n = initVuei18n()
export default i18n

4. 挂载

// main.js
...
import i18n from './plugin/vuei18n/index'
new Vue({
  router,
  store,
  i18n, // 挂载到全局
  render: h => h(App)
}).$mount('#app')

5. 使用

i18n挂载到全局之后,内部会把i18n合并到Vue实例上,新加属性$i18n, $t 等属性方法

// 在模板上直接使用
<a-button type="link">{
   
   { $t('link.homeLink') }}</a-button>
<a-button type="link">{
   
   { $t('link.detailLink') }}</a-button>
// 切换语言
methods: {
    // 切换语言
    switchLanguage (type) {
      this.$i18n.locale = type
    }
}

Ant-Design-Vue 国际化的支持

在app.vue文件中使用ConfigProvider组件包裹住router-view,引入ant-design-vue多语言文件

注意:LocaleProvider 已经废弃了 换成 ConfigProvider

// app.vue
<template>
  <div id="app">
    <a-config-provider :locale="locale">
      <router-view/>
    </a-config-provider>
  </div>
</template>

<script>
// 引入antdesignvue的语言包
import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN'
import enUS from 'ant-design-vue/lib/locale-provider/en_US'
export default {
  data () {
    return {
      locale: zhCN,
      lang: {
        'zh-CN': zhCN,
        'en-US': enUS
      }
    }
  }
}
</script>

全局监听切换语言

使用事件总线,全局监听切换语言时更改语言配置,用stroe存储当前语言选项

// 在main.js 中定义事件总线
new Vue({
  router,
  store,
  i18n,
  render: h => h(App),
  data: { Bus: new Vue() } // 定义事件总线
}).$mount('#app')

在app.vue中可以使用this.$root.Bus.$on监听事件,在切换语言的界面使用this.$root.Bus.$emit触发事件

// 在切换语言的界面.vue
methods: {
    // 切换语言
    switchLanguage (type) {
      this.$root.Bus.$emit('switchLanguage', type)
    }
}
// app.vue
<template>
  <div id="app">
    <a-config-provider :locale="locale">
      <router-view/>
    </a-config-provider>
  </div>
</template>

<script>
// 引入antdesignvue的语言包
import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN'
import enUS from 'ant-design-vue/lib/locale-provider/en_US'
export default {
  data () {
    return {
      locale: zhCN, // 默认中文
      lang: {
        'zh-CN': zhCN,
        'en-US': enUS
      }
    }
  },
  created () {
    this.$root.Bus.$on('switchLanguage', type => {
      this.$i18n.locale = type
      this.locale = this.lang[type]
      this.$store.commit('updateState', { key: 'locale', value: type }) // 存到store
    })
  }
}
</script>

根据语言切换css

同一句话在切换语言的时候会因为文字的长度不同,导致页面上的样式结构错位。因此可能需要准备两套的样式,根据不同语言,动态的去切换每个页面根元素的class

// example.vue

<template>
  <div class="internationalView" :class="langClass">
    <div class="lang-wrap">
      <a-button type="primary" @click="switchLanguage('zh-CN')"> 中文 </a-button>
      <a-button style="margin-left: 20px" @click="switchLanguage('en-US')"> English</a-button>
    </div>
    <p class="detail">{
   
   { $t('link.detailLink') }}</p>
  </div>
</template>

<script>
export default {
  name: 'internationalView',
  computed: {
    langClass () {
      return this.$store.state.locale
    }
  },
  methods: {
    // 切换语言
    switchLanguage (type) {
      this.$root.Bus.$emit('switchLanguage', type)
    }
  }
}
</script>
<style lang="less" scoped>
.zh-CN {
  .detail {
    color: red;
  }
}
.en-US {
  .detail {
    color: green;
  }
}
</style>

~~~ end ~~~

猜你喜欢

转载自blog.csdn.net/weixin_45313351/article/details/128327855