Vue项目中如何做好国际化

81 阅读4分钟

大家好!今天没给大家介绍的是Vue 项目中如何做好国际化, 为什么要做国际化呢? 因为我们所在的公司用很可能还有国外的。 比如我之前所在的公司的产品百分之八九十的都是国外用户。 如果我们的产品,我们的项目全部还是中文的, 那肯定是不行的。因此,国际化的实现是提升用户体验、拓展市场的重要手段。本文将详细介绍如何在 Vue 项目中实现国际化,并结合 vue-i18nelement-plus 的实际使用案例,帮助开发者快速掌握这一技能。

为什么需要国际化?

国际化可以提升用户体验,增加用户广度。

接下来,我们将以 Vue3 项目为例,逐步实现国际化支持。

创建Vue3 项目

首先初始化一个Vue3 项目, 这里我使用vite 创建。

执行以下命令就进行项目创建:

pnpm create vite vue-lang

执行以下命令切换到项目目录

cd vue-lang

运行项目: pnpm run dev

安装i18n

pnpm i vue-i18n

使用vue-i18n

目录结构创建

src
 └── lang
      ├── en.js  // 英文语言包
      ├── zh.js  // 中文语言包
      ├── fr.js  // 法语语言包
      └── index.js  // 汇总语言包

编写语言包文件

英文语言包(en.js):

export default {
  message: {
    hello: "hello world",
  },
};

中文语言包(zh.js):

export default {
  message: {
    hello: "你好世界",
  },
};

法语语言包(fr.js):

export default {
  message: {
    hello: "Bonjour, le monde",
  },
};

汇总语言包(index.js)

import { createI18n } from "vue-i18n";

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

const i18n = createI18n({
  legacy: false, // 设置使用组合式api
  locale: "en", // 设置默认语言
  messages: { // 加载语言包
    en,
    zh,
    fr,
  },
});

export default i18n;

这里可以看到:

  • 我们从vue-i18n 中导入了一个方法,这个方法传入一个对象。对象里面包含了3个属性。
  • legacy 设置为false 的意思是使用组合式api, 不设置的话,最新版本在控制台会有警告。
  • locale 设置初始化语言。
  • messages 就是我们之前编写的语言包。

配置国际化到 Vue 项目

main.js 中引入 vue-i18n

import { createApp } from "vue";
import App from "./App.vue";

import i18n from "./lang";
const app = createApp(App);
app.use(i18n);
app.mount("#app");

主要增加了两行代码:

import i18n from "./lang";
app.use(i18n);

在组件中使用国际化

<template>
  <div>
    <p>{{ $t('message.hello') }}</p>
  </div>
</template>

<script setup>
</script>

<style scoped>
</style>

组件里面使用的时候使用$t方法,这里还需要注意的是message这个单词,这是我们在每个语言里面定义的字段

image.png

如果我们把message 改成text的话,模板里面使用就需要改成{{$t('text.hello')}}

查看运行效果:

image.png

可以看到显示的是英文, 为什么显示的是英文呢?因为我们在createI18n传入的对象属性,locale 字段设置的值是en, 如果我们想显示中文,只需要将值改成zh即可。

这样一个国际化就开发完成了。

处理动态参数

有时项目里面的文案不写死的,有一段需要拼接,比如现在有一句话: 今天走了10000步,这里的10000需要做成动态的。该怎么做呢?

我们我们修改语言包: 以中文为例,

export default {
  message: {
    hello: "你好世界",
    motion: "我今天走了{count}步",
  },
};

修改App.vue组件

<template>
  <div>
    <p>{{ $t('message.hello') }}</p>
    <p>{{ $t('message.motion', { count }) }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue'
const count = ref(10000)
</script>

<style scoped>
</style>

查看运行效果:

image.png

可以看到结果符合预期:

小结: vue-i18n 动态参数,在语言包里面采用{text}的形式读取值,组件组件模板里面,$t方法的第二个参数对象属性进行传入。

vue-i18n 和element plus 结合一起国际化

安装element-plus

pnpm i element-plus

修改main.js

import { createApp } from "vue";
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
import App from "./App.vue";

import i18n from "./lang";
const app = createApp(App);

app.use(ElementPlus);
app.use(i18n);
app.mount("#app");

主要新增了三行代码:

import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
app.use(ElementPlus);

修改App.vue

<template>
  <ElConfigProvider :locale="elementLocale">
  <div>
    <p>{{ $t('message.hello') }}</p>
    <p>{{ $t('message.motion', { count }) }}</p>
    <el-date-picker
        v-model="dateTime"
        type="date"
      />

      <el-select v-model="value" placeholder="Select" @change="setLang" style="width: 240px">
        <el-option
          v-for="item in options"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
  </div>
</ElConfigProvider>
  
</template>

<script setup>
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
import enPlus from "element-plus/es/locale/lang/en";
import zhCnPlus from "element-plus/es/locale/lang/zh-cn";
import frPlus from "element-plus/es/locale/lang/fr";
const count = ref(10000)

const dateTime = ref('')
const {locale} =  useI18n()


const options = [
  {
    value: 'en',
    label: '英文',
  },
  {
    value: 'zh',
    label: '中文',
  },
  {
    value: 'fr',
    label: '法语',
  }
]

const value = ref('en')
const elementLocale = ref(enPlus)

const setLang = (lang) => {
  console.log(lang)
  locale.value = lang
  const config = {
    en: enPlus,
    zh: zhCnPlus,
    fr: frPlus
  }
  elementLocale.value = config[lang]
}
</script>

<style scoped>
</style>

在App.vue 中:

  • 新增了3个element-plus 语言包的导入
import enPlus from "element-plus/es/locale/lang/en";
import zhCnPlus from "element-plus/es/locale/lang/zh-cn";
import frPlus from "element-plus/es/locale/lang/fr";
  • 模板中新增了一个下拉框组件用来切换语言
  • 新增了useI18nvue-in18中导入的方法, 这个方法执行会得到一个解构的locale, 修改了locale的值就会修改我们的语言
  • 在下拉选择设置的方法中,还新增了以下代码用于设置element-plus的语言
const config = {
    en: enPlus,
    zh: zhCnPlus,
    fr: frPlus
  }
  elementLocale.value = config[lang]
  • 在模板中我们用element-plus 的组件ElConfigProvider 包裹了我们写的代码,并且还添加了:locale="elementLocale" 。 这个组件和这个属性的作用就是用来动态修改element-plus 的语言

现在我们来查看下运行效果:

vue-lang.gif

可以看到我们自己写的文案和element-plus 的文案都跟着变了。

总结

通过本文的详细步骤,我们实现了以下功能:

  1. 基于 vue-i18n 的国际化。
  2. 用户手动切换语言
  3. vue-i18nelement-pluis 的国际化进行联动

国际化是一个复杂但非常重要的功能,合理地实现国际化可以显著提升产品的用户体验和市场竞争力。希望本文能为您带来帮助!