Vite3+Vue3+TypeScript+Element Plus (十四) 搭建企业级轻量框架实践

644 阅读2分钟

我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第4篇文章

前言

i18n(其来源是英文单词 internationalization的首末字符i和n,18为中间的字符数)是“国际化”的简称。在资讯领域,国际化(i18n)指让产品(出版物,软件,硬件等)无需做大的改变就能够适应不同的语言和地区的需要。对程序来说,在不修改内部代码的情况下,能根据不同语言及地区显示相应的界面。 在全球化的时代,国际化尤为重要,因为产品的潜在用户可能来自世界的各个角落。

🍏推荐阅读

Vue I18n

Vue I18n 是 Vue.js 的国际化插件。它可以轻松地将一些本地化功能集成到您的 Vue.js 应用程序中。

安装

# PNPM
pnpm i vue-i18n -S

I18n

import { App } from 'vue'
import { type I18n, createI18n } from 'vue-i18n'

const i18n: I18n = createI18n({
  legacy: false,
  locale: 'zh',
  fallbackLocale: 'en',
  messages: {
    en: { hello: 'hi there!' },
    zh: { hello: '你好 !' },
  },
})

export function setupI18n(app: App) {
  app.use(i18n)
  return i18n
}

挂载

在main.ts中引入i18n并挂载,代码如下:

import 'vue-global-api'
import App from './App.vue'
import { createApp } from 'vue'
import { bootstrap } from '~/library'
import { setupI18n } from '@/i18n'
import { setupStore } from '@/store'
const app = createApp(App)
bootstrap(app)
setupI18n(app)
setupStore(app)
app.mount('#app')

unplugin.ts

自动导入vue-i18n相关函数

import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'
import { FileSystemIconLoader } from 'unplugin-icons/loaders'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export function configAutoImportPlugin() {
  return AutoImport({
    imports: ['vue', 'vue-i18n', 'vue-router', 'pinia'],
    resolvers: [ElementPlusResolver({ importStyle: false })],
    // 指定文件生成路径
    dts: 'config/unplugin/auto-imports.d.ts',
    eslintrc: {
      enabled: true, // Default `false`
      filepath: './.eslintrc-auto-import.json', // Default `./.eslintrc-auto-import.json`
      globalsPropValue: true, // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')
    },
  })
}
...

App.vue

<script setup lang="ts" name="App"></script>

<template>
  <!-- string literal -->
  <p v-t="'hello'"></p>
  <p>message: {{ $t('hello') }}</p>
</template>

与 Vite 捆绑

vite-plugin-vue-i18n

vite-plugin-vue-i18nVite的 vite 插件。

安装

# PNPM
pnpm i @intlify/vite-plugin-vue-i18n -D

添加配置

import { resolve } from 'path'
import vue from '@vitejs/plugin-vue'
import vueSetupExtend from 'vite-plugin-vue-setup-extend'
import VueI18n from '@intlify/vite-plugin-vue-i18n'
import legacy from '@vitejs/plugin-legacy'
import { configMockPlugin } from './mock'
import { configCompressPlugin } from './compress'
import { configImageminPlugin } from './imagemin'
import { configStyleImportPlugin } from './style'
import { configAutoImportPlugin, configVueComponentsPlugin, configVueIconsPlugin } from './unplugin'
export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
  const {
    VITE_USE_IMAGEMIN,
    VITE_USE_COMPRESS,
    VITE_COMPRESS_DELETE_ORIGIN_FILE,
    VITE_USE_MOCK,
    VITE_LEGACY,
  } = viteEnv
  const plugins = [
    vue(),
    vueSetupExtend(),
    // https://github.com/intlify/bundle-tools/tree/main/packages/vite-plugin-vue-i18n
    VueI18n({
      runtimeOnly: true,
      compositionOnly: true,
      include: [resolve('locales/**')],
    }),
    // 是否为打包后的文件提供传统浏览器兼容性支持
    VITE_LEGACY
      ? legacy({
          targets: ['ie >= 11'],
          additionalLegacyPolyfills: ['regenerator-runtime/runtime'],
        })
      : null,
  ]
  // vite-plugin-mock
  VITE_USE_MOCK && plugins.push(configMockPlugin(isBuild))
  if (isBuild) {
    // vite-plugin-compress
    VITE_USE_COMPRESS && plugins.push(configCompressPlugin(VITE_COMPRESS_DELETE_ORIGIN_FILE))
    // vite-plugin-imagemin
    VITE_USE_IMAGEMIN && plugins.push(configImageminPlugin())
  }
  // unplugin-auto-import
  plugins.push(configAutoImportPlugin())
  // unplugin-vue-components
  plugins.push(configVueComponentsPlugin())
  // vite-plugin-style-import
  plugins.push(configStyleImportPlugin())
  // unplugin-icons
  plugins.push(configVueIconsPlugin())
  return plugins
}

zh-CN.yaml

login:
  username: 账号
  password: 密码
  verifyCode: 验证码
  remember: 记住密码
  forget: 忘记密码?
  login: 登录
  loginSuccess: 登录成功
menus:
  login: 登录
  home: 首页

加载本地国际化配置

import { App } from 'vue'
import { type I18n, createI18n } from 'vue-i18n'

// 加载国际化配置
function siphonI18n(prefix = 'zh-CN') {
  return Object.fromEntries(
    Object.entries(import.meta.glob('~/locales/*.y(a)?ml', { eager: true })).map(
      ([key, value]: any) => {
        const matched = key.match(/([A-Za-z0-9-_]+)\./i)[1]
        return [matched, value.default]
      }
    )
  )[prefix]
}

const i18n: I18n = createI18n({
  legacy: false,
  locale: 'zh',
  fallbackLocale: 'en',
  messages: {
    en: { hello: 'hi there!', ...siphonI18n('en') },
    zh: { hello: '你好 !', ...siphonI18n('zh-CN') },
  },
})

export function setupI18n(app: App) {
  app.use(i18n)
  return i18n
}

App.vue

<script setup lang="ts" name="App"></script>

<template>
  <!-- string literal -->
  <p v-t="'hello'"></p>
  <p>message: {{ $t('hello') }}</p>
  <p>locales: {{ $t('menus.home') }}</p>
</template>

代码已经提交到Gitee

继续学习

废话只说一句:码字不易求个👍,收藏 === 学会,快行动起来吧!🙇‍🙇‍🙇‍。

# Vite+Vue3+TypeScript+Element (十五) 搭建企业级轻量框架实践