小白学 VUE 系列Vue I18n 国际化插件使用教程

Vue I18n 是 Vue.js 的国际化插件

手册地址:https://kazupon.github.io/vue-i18n/zh/

安装

vue2版本

npm install vue-i18n@8

vue3

npm install vue-i18n@9

快速引入使用

src 下新建语言包 lang 文件夹,并创建语言包文件和引入文件index.jz,例如:zh.js,en.js

lang
    index.js
    zh.js
    en.js

index.js

import Vue from 'vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)

import zh from './zh'
import en from './en'

const messages = {
    en,
    zh
  }
  const i18n = new VueI18n({
    locale: 'zh', // 设置地区
    messages, // 设置地区信息
  })
  export default i18n;

zh.js

export default{
    main:{
        message:"消息",
        display:'显示'

    }

}

en.js

export default{
    main:{
        message:"message",
        display:'show'

    }

}

main.js引入

new Vue({
  router,
  store,
  i18n,
  render: h => h(App)
}).$mount('#app')

调用

<template>
  <div id="app">

      <h1>{{ $t('main.message') }}</h1>
      <select v-model="language" @change="changeLang">
        <option value="zh">中文</option>
        <option value="en">英文</option>
      </select>
    <router-view />
  </div>
</template>
<script>
export default {
  name:'App',
  data() {
    return {
        language:''

    }
  },
  methods: {
    changeLang(){
      console.log('改变语言',this.language)
      this.$i18n.locale=this.language
    }
  }
}
</script>

语言包语法

对象形式传参

const messages = {
  en: {
    message: {
      hello: '{msg} world'
    }
  }
}

<p>{{ $t('message.hello', { msg: 'hello' }) }}</p>

数组形式

const messages = {
  en: {
    message: {
      hello: '{0} world'
    }
  }
}

<p>{{ $t('message.hello', ['hello']) }}</p>

含有html输出

const messages = {
  en: {
    message: {
      hello: 'hello <br> world'
    }
  }
}

<p v-html="$t('message.hello')"></p>

复数

使用函数 $tc() 调用

可以通过预定义的命名参数 {count} 和/或 {n} 在语言环境信息中访问该数字

const messages = {
  en: {
    car: 'car | cars',
    apple: 'no apples | one apple | {count} apples'
  }
}

> 模板

<p>{{ $tc('car', 1) }}</p>
<p>{{ $tc('car', 2) }}</p>

<p>{{ $tc('apple', 0) }}</p>
<p>{{ $tc('apple', 1) }}</p>
<p>{{ $tc('apple', 10, { count: 10 }) }}</p>

输出如下:

<p>car</p>
<p>cars</p>

<p>no apples</p>
<p>one apple</p>
<p>10 apples</p>

日期

const dateTimeFormats = {
  'en-US': {
    short: {
      year: 'numeric',
      month: 'short',
      day: 'numeric'
    },
    long: {
      year: 'numeric',
      month: 'long',
      day: 'numeric',
      weekday: 'long',
      hour: 'numeric',
      minute: 'numeric'
    }
  },
  'zh-CN': {
    short: {
      year: 'numeric',
      month: 'short',
      day: 'numeric'
    },
    long: {
      year: 'numeric',
      month: 'long',
      day: 'numeric',
      weekday: 'long',
      hour: 'numeric',
      minute: 'numeric',
      hour12: false
    }
  }
}

const i18n = new VueI18n({
  dateTimeFormats
})

<div id="app">
  <p>{{ $d(new Date(), 'short') }}</p>
  <p>{{ $d(new Date(), 'long', 'zh-CN') }}</p>
</div>

如果没有定义 fallbackLocale 这个值,则默认显示是英文的格式,如果设置了中文,则显示中文
  const i18n = new VueI18n({
    locale: 'zh-CN', // 设置地区
    messages, // 设置地区信息
    dateTimeFormats,
    fallbackLocale: 'zh-CN',
  })

  export default i18n;
<div id="app">
  <p>{{ $d(new Date(), 'short') }}</p>
  <p>{{ $d(new Date(), 'long', 'zh-CN') }}</p>
</div>

2023年6月10日

2023年6月10日星期六 21:35

数字本地化

可以使用你定义的格式来本地化数字。

const numberFormats = {
  "en-US": {
    currency: {
      style: "currency",
      currency: "USD",
    },
  },
  "zh-CN": {
    currency: {
      style: "currency",
      currency: "CNY",
    },
  },
  "ja-JP": {
    currency: {
      style: "currency",
      currency: "JPY",
      currencyDisplay: "symbol",
    },
  },
};

const i18n = new VueI18n({
  numberFormats
})

new Vue({
  i18n
}).$mount('#app')

<div id="app">
  <p>{{ $n(100, 'currency') }}</p>
  <p>{{ $n(100, 'currency', 'zh-CN') }}</p>
</div>

回退本地化

总结:使用fallbackLocale:<lang>选择首选语言缺少翻译时要使用的语言。

const i18n = new VueI18n({
  locale: 'zh-CN',
  fallbackLocale: 'en',
  messages
})

如果默认找不到 zh-CN 翻译,则调用en

组件的本地化

因此你可以全局地在 Vue 的根实例以及任何被组合的组件中使用 $t 或者 $tc 进行翻译。当然面向 Vue 组件的设计,你也可以更方便的分别控制每个组件的语言环境信息

const Component1 = {
  template: `
    <div class="container">
     <p>Component1 locale messages: {{ $t("message.hello") }}</p>
     <p>Fallback global locale messages: {{ $t("message.greeting") }}</p>
   </div>`,
  i18n: { // `i18n` 选项,为组件设置语言环境信息
    messages: {
      en: { message: { hello: 'hello component1' } },
      zh: { message: { hello: '你好 component1' } }
    }
  }
}

如果组件内定义了,则调用的话,则调用组件内的翻译。

组件的共享语言环境消息

import commonMessage from './locales/common' // 导入通用语言环境消息

export default {
  name: 'ServiceModal',
  template: `
    <div class="modal">
      <div class="body">
        <p>This is good service</p>
      </div>
      <div class="footer">
        <button type="button">
          {{ $t('buttons.save') }}
        </button>
      </div>
    </div>
  `,
  i18n: {
    messages: { ... },
    sharedMessages: commonMessages
  }
}

自定义指令本地化

除了可以使用 $t 函数调用之外,还可以使用指令,例如v-t

v-t 比 $t 方法具有更好的性能,因为在一次翻译时自定义指令会进行缓存,$t 在每次重新渲染时都会被执行

div id="string-syntax">
  <!-- 字符串 -->
  <p v-t="'hello'"></p>
  <!-- 通过数据进行键名路径绑定 -->
  <p v-t="path"></p>
</div>

对象语法

<div id="object-syntax">
  <!-- 文字 -->
  <p v-t="{ path:'hello', locale:'ja', args: { name:'kazupon'} }"></p>
  <!-- 通过 `data` 绑定数据 -->
  <p v-t="{ path: path, args: { name: nickName } }"></p>
</div>

切换语言简单例子

 <select v-model="locale" >
        <option value="zh">中文</option>
        <option value="en">英文</option>
      </select>

export default {
  name:'App',
  data() {
    return {
        locale:'zh-CN'
    }
  },
  watch: {
    locale(val){
      this.$i18n.locale=val
    }
  },
  methods: {

  }
}

懒加载语言包

一次加载所有翻译文件是过度和不必要的。使用 Webpack 时,延迟加载或异步加载转换文件非常简单
例如我们在创建了lang/index.js,语言包目录也在lang 下面,则例子如下:

import Vue from "vue";
import VueI18n from "vue-i18n";
Vue.use(VueI18n);

import zh from "./zh";
import en from "./en";

const messages = {
    en,
    "zh-CN": zh,
};

export const i18n = new VueI18n({
    locale: "zh-CN", // 设置地区
    messages, // 设置地区信息
    fallbackLocale: "zh-CN",

});

const loadedLanguages = [i18n.locale] // 我们的预装默认语言

function setI18nLanguage(lang) {
    i18n.locale = lang
    document.querySelector('html').setAttribute('lang', lang)
    return lang
}

export function loadLanguageAsync(lang) {

    // 如果语言相同
    if (i18n.locale === lang) {
        return Promise.resolve(setI18nLanguage(lang))
    }

    // 如果语言已经加载
    if (loadedLanguages.includes(lang)) {

        return Promise.resolve(setI18nLanguage(lang))
    }

    // 如果尚未加载语言
    return import(`@/lang/${lang}.js`).then(
        messages => {
            i18n.setLocaleMessage(lang, messages.default)
            loadedLanguages.push(lang)
            return setI18nLanguage(lang)
        }
    )
}
  • 其中 @ 表示 src 目录

路由拦截一下

import {i18n,loadLanguageAsync} from './lang'
......

router.beforeEach((to, from, next) => {
  const lang = to.params.lang ||  'zh-CN';
  loadLanguageAsync(lang).then(() => next())
})

new Vue({
  router,
  store,
  i18n,
  render: h => h(App)
}).$mount('#app')

评论区 (0)

没有记录
支持 markdown,图片截图粘贴拖拽都可以自动上传。
黑白课堂

黑白课堂 · 技术专家

专业PHP开发

年度VIP 站长创业者玉树凌风每天醒来0收入
查看更多

最新视频课程