简单好懂的 Vue + i18n 配置方案

153 阅读1分钟

安装依赖

npm install vue-i18n

在 main.ts 中引用

import i18n from './locales'

//...
app.use(i18n)

src 目录下新建一个 locales 文件夹

目录结构

|-src
|---locales
|------en.ts
|------index.ts
|------zh-cn.ts

index.ts

import { createI18n } from 'vue-i18n'
import elementEnLocale from 'element-plus/lib/locale/lang/en'
import elementZhLocale from 'element-plus/lib/locale/lang/zh-cn'

import enLocale from './en'
import zhLocale from './zh-cn'

// 将自定义的英文和中文语言、`element-plus`的英文和中文语言包配置文件合并进来
export const messages = {
  en: {
    ...enLocale,
    ...elementEnLocale
  },
  'zh-cn': {
    ...zhLocale,
    ...elementZhLocale
  }
}

// 首先尝试从本地存储中获取语言设置,如果获取不到或者获取的语言设置不在支持的语言列表中,
// 则默认返回中文`zh-cn`作为语言设置
export const getLocale = () => {
  const language = localStorage.getItem('lang') || ''
  const locales = Object.keys(messages)
  if (locales.includes(language)) {
    return language
  }
  return 'zh-cn'
}

const i18n = createI18n({
  locale: getLocale(),
  messages,
  legacy: false
})

export default i18n

en.ts

export default {
  header: {
    title: 'title',
    placeholder: 'placeholder'
  },
  placeholder: {
    keyword: 'keyword'
  },
}

zh-cn.ts

export default {
  header: {
    title: '标题',
    placeholder: '占位符'
  },
  placeholder: {
    keyword: '关键词',
  }
}

切换中英文组件

使用 el-dropdown 组件

<template>
  <el-dropdown>
    <i class="iconfont icon-language"></i>
    <template #dropdown>
      <el-dropdown-menu>
        <el-dropdown-item :disabled="locale === 'zh-cn'" @click="setLang('zh-cn')"
          >中文</el-dropdown-item
        >
        <el-dropdown-item :disabled="locale === 'en'" @click="setLang('en')"
          >English</el-dropdown-item
        >
      </el-dropdown-menu>
    </template>
  </el-dropdown>
</template>

<script lang="ts" setup>
import { useI18n } from 'vue-i18n'

const { locale, t: tLang } = useI18n()

const setLang = (lang: 'zh-cn' | 'en') => {
  locale.value = lang
  localStorage.setItem('lang', lang)
  document.title = tLang('header.title')
}
</script>

image.png

组件中替换

<template>
  <el-input v-model="keyword" :placeholder="tLang('header.placeholder')" />
</template>

<script setup lang="ts">
import { useI18n } from 'vue-i18n'

const { t: tLang } = useI18n()
</script>