vue-i18n 多语言(国际化) 切换 初学使用


vue-i18n 多语言(国际化) 切换 初学使用

不少网站有多语言模式,正好项目里需要多语言切换,简单学习之后,整理成文章,加深记忆。

概述

Vue I18n 是 Vue.js 的国际化插件,格局比较大,具体怎么解释还是不太好说,直接看用法就能明白。简单说一下为什么叫这个名字:internationalization(i+中间的18个字母+n)。

如果你更喜欢看官方文档可以移步下面的官方文档,本文只是基本使用,看本文你也可以学会基本使用
i18n官网: https://kazupon.github.io/vue-i18n/zh/

本文案例环境:

  • "vue": "^2.6.11",
  • "vue-i18n": "^8.23.0",

安装

  • 安装vue-I18n插件
//需要使用npm进行安装8.x版本
npm install vue-i18n@8.23.0

注:如果按照使用时候报一堆错误,找不到变量,可能是i18n版本太高了,与当前VUE版本不兼容,我的项目vue版本是2.6.11,开始我就安装的i18n版本是9.x,一直报错找不到原因,我就试着把i18n版本降低到8.x就不报错了

  • 在项目中配置i18n
    main.js 中引入 vue-i18n
import Vue from 'vue' // 先引入vue
import VueI18n from 'vue-i18n'//引入对应的组件
Vue.use(VueI18n);//挂载使用i18n的插件

设置本地语言来挂载不同的信息(变量)

通常语言环境信息 (例如:localemessages 等) 会被设置为 VueI18n 实例的构造函数选项,并且该实例会被作为 i18n 选项设置在 Vue 的根实例上。

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

main.js 中引入 vue-i18n

// 为 Vue 的根实例设置语言环境信息
// 通过选项创建 VueI18n 实例
const i18n = new VueI18n({
  //基本常见,多语言网页,使用this.$i18n.locale="zh";可以修改对应的语言模式,其处理一般放在一个lang文件下
  //封装处理多个语言, 大小写均可,这就是messages对象里面的key
  locale: 'CN',
  // 首选语言缺少翻译时要使用的语言。如果某个语言环境没有设置变量,就会使用fallbackLocale环境下的对应变量
  fallbackLocale: 'CN',
  //抑制警告
  silentFallbackWarn: true,
  // 语言对照表
  messages: {
    US: {
      msg: {
        hello: 'english'
      },
    },
    CN: {
      msg: {
        hello: '简体'
      }
    },
    HK: {
      msg: {
        hello: '繁體'
      }
    },
    DD: {
      msg: {
        // 在模板里获取DD语言的hello时,会默认使用fallbackLocale环境下的值
      }
    }
  }
});


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

模板中使用:

//App.vue组件中的使用举例了(由于挂载到了app上面,因此可以在任意组件中使用该地区信息,即:messages)
//使用形式如下:
{{ $t("msg.hello") }}

在上面的例子中,如果组件没有语言环境信息,它将回退到全局定义的本地化信息。组件使用根实例中设置的语言 (在上面的例子中:locale: 'CN')。

注意,在默认情况下,回退到根语言环境会在控制台中生成两个警告:

[vue-i18n] Value of key 'msg.hellp' is not a string!
[vue-i18n] Fall back to translate the keypath 'msg.hellp' with root locale.

为避免以上警告 (同时保留那些完全没有翻译给定关键字的警告) 需初始化 VueI18n 实例时设置 silentFallbackWarn: true

如果你希望在组件语言环境中进行本地化,可以在 i18n 选项中用 sync: falselocale

语言环境变更

通常,使用 Vue 根实例作为起点,使用 VueI18n 类的 locale 属性作为参考来本地化所有子组件。

有时你可能希望动态更改语言环境。在这种情况下,你可以更改 VueI18n 实例的 locale 属性的值。

const i18n = new VueI18n({
  locale: 'CN', // 设置语言环境
  ...
})

// 创建 Vue 根实例
new Vue({
  i18n,
  ...
}).$mount('#app')

// 更改为其它的 locale
i18n.locale = 'EN'

在模板中修改locale的值

// 更改为其它的 locale
this.$i18n.locale = 'EN'

每个组件都包含一个引用为 $i18n 属性的 VueI18n 实例,该实例也可用于更改语言环境。

对于使用了 sync: false 的组件,语言环境的更改将被忽略。
在组件内更改 $i18n.locale 不会更新根语言环境。 如果您依靠根语言环境,例如在使用 root fallbacks 时,请使用 $root.$i18n.locale 而不是$i18n.locale

格式化

  • 具名格式

语言环境信息如下:

const messages = {
  CN: {
    message: {
      hello: '{msg}简体{name}'  //没看错这里就是字符串,不用`` ,es6的模板编译这样写
    }
  }
}

模板如下:

{{ $t("msg.hello", { name: '较瘦', msg: 999 } ) }}

输出如下:

999简体较瘦

  • 列表格式

语言环境信息如下:

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

模板如下:

{{ $t('message.hello', ['hello']) }}

输出如下:

hello world

列表格式也接受类似数组的对象:

{{ $t('message.hello', {'0': 'hello'}) }}

输出如下:

hello world

  • HTML 格式化

在你的网站上动态插入任意 HTML 可能非常危险,因为它很容易导致 XSS 攻击。仅对可信内容使用 HTML 插值,而不对用户提供的内容使用。我们建议使用组件插值 功能。

在某些情况下,你可能希望将翻译呈现为 HTML 信息而不是静态字符串。

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

模板如下:

输出如下 (取代预先格式化的信息)

hello world

下面就是官方文档翻译了,可以移步官方查看
下面就是官方文档翻译了,可以移步官方查看
下面就是官方文档翻译了,可以移步官方查看

复数

你可以使用复数进行翻译。你必须定义具有管道 | 分隔符的语言环境,并在管道分隔符中定义复数。

您的模板将需要使用 $tc() 而不是 $t()

语言环境信息如下:

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

模板如下:

{{ $tc('car', 1) }}

{{ $tc('car', 2) }}

{{ $tc('apple', 0) }}

{{ $tc('apple', 1) }}

{{ $tc('apple', 10, { count: 10 }) }}

输出如下:

car

cars

no apples

one apple

10 apples

  • 通过预定义的参数访问该数字
    你无需明确指定复数的数字。可以通过预定义的命名参数 {count} 和/或 {n} 在语言环境信息中访问该数字。如有必要,你可以覆盖这些预定义的命名参数。

语言环境信息如下:

const messages = {
  en: {
    apple: 'no apples | one apple | {count} apples',
    banana: 'no bananas | {n} banana | {n} bananas'
  }
}

模板如下:

{{ $tc('apple', 10, { count: 10 }) }}

{{ $tc('apple', 10) }}

{{ $tc('banana', 1, { n: 1 }) }}

{{ $tc('banana', 1) }}

{{ $tc('banana', 100, { n: 'too many' }) }}

输出如下:

10 apples

10 apples

1 banana

1 banana

too many bananas

语言环境信息的语法

  • Linked locale messages

如果有一个翻译关键字总是与另一个具有相同的具体文本,你可以链接到它。要链接到另一个翻译关键字,你所要做的就是在其内容前加上一个 @: 符号后跟完整的翻译键名,包括你要链接到的命名空间。

语言环境信息如下:

const messages = {
  en: {
    message: {
      the_world: 'the world',
      dio: 'DIO:',
      linked: '@:message.dio @:message.the_world !!!!'
    }
  }
}

模板如下:

{{ $t('message.linked') }}

输出如下:

DIO: the world !!!!

  • 格式化链接的语言环境消息
    如果语言区分字符大小写,则可能需要控制链接的语言环境消息的大小写。 链接的消息可以用修饰符 @.modifier:key 格式化。

以下修饰符当前可用。

  • upper: 链接消息中的所有字符均大写
  • lower: 小写链接消息中的所有字符
  • capitalize: 大写链接消息中的第一个字符

语言环境消息如下:

const messages = {
  en: {
    message: {
      homeAddress: 'Home address',
      missingHomeAddress: 'Please provide @.lower:message.homeAddress'
    }
  }
}


{{ $t('message.missingHomeAddress') }}

输出以下内容:



Please provide home address

您可以添加修饰符或覆盖将 modifiers 选项传递给 VueI18n 构造函数的现有修饰符。

const i18n = new VueI18n({
  locale: 'en',
  modifiers: {
    snakeCase: (str) => str.split(' ').join('-')
  },
  messages: {
    // ...
  },
})

  • 按括号分组
    链接到的语言环境信息的键名也可以形如 @:(message.foo.bar.baz),其中链接到另一段翻译的键名在括号 () 里。

如果链接 @:message.something 后紧跟着一个点 .,则此选项非常有用,因为它本不该成为但却成为了链接的一部分。

语言环境信息如下:

const messages = {
  en: {
    message: {
      dio: 'DIO',
      linked: 'There\'s a reason, you lost, @:(message.dio).'
    }
  }
}

模板如下:

{{ $t('message.linked') }}

输出如下:

There's a reason, you lost, DIO.

  • 函数功能
    vue-i18n 建议在翻译消息时使用基于列表的字符串或命名格式作为语言环境消息。

但是,在某些情况下,由于复杂的语言语法,您确实需要JavaScript的全部编程功能。 因此,您可以使用 message function 来代替基于字符串的消息。

以下是一个返回简单问候语的消息函数:

const messages = {
  en: {
    greeting: (ctx) => 'hello!'
  }
}

使用消息功能非常容易! 您只需使用 $tt 指定消息功能的键:

{{ $t('greeting') }}

输出如下:

hello!

消息功能输出消息,该消息具有消息功能的返回值。

  • 命名格式
    vue-i18n 支持命名格式 作为基于字符串的消息格式。 vue-i18n用$tt插值参数值,并可以将其输出。

使用 消息上下文 的消息功能可以完成以下操作:

这是问候的示例:

const messages = {
  en: {
    greeting: (ctx) => `hello, ${ctx.named('name')}!`
  }
}

模板:

{{ $t('greeting', { name: 'DIO' }) }}

输出如下:

hello, DIO!

消息上下文具有命名函数。 您需要指定键来解析以 $tt 命名的值。

  • 清单格式
    列表格式的使用类似于上述命名格式。

vue-i18n 支持 列表格式 作为基于字符串的消息格式。 vue-i18n用$ t或t插值参数值,并可以将其输出。

您可以通过使用消息上下文对消息函数执行相同的操作:

这是问候的示例:

const messages = {
  en: {
    greeting: (ctx) => `hello, ${ctx.list(0)}!`
  }
}

模板:

{{ $t('greeting', ['DIO']) }}

输出如下:

hello, DIO!

消息上下文具有列表功能。 您需要指定索引来解析由 $tt 列表指定的值。

vue