当前位置:   article > 正文

vite项目中vue-i18n国际化与Element-Plus自动导入结合实现_vitest引入国际化

vitest引入国际化

前言

之前就想使用i18n国际化插件,但是一直没有使用的机会,正好这次要搭建一个vite+vue3的基础项目,使用了Element-plus框架,并设设置自动引入组件,刚好也需要设置国际化,所以打算将两者结合使用,通过结合Element-plus与vue-i18n的方式来实现多语言切换,废话不多说现在开始吧!(注:之前已经搭好了基本的框架,详细可以参考vue3+vite项目配置ESlint、pritter插件

Element-Plus引入使用

与Vue相配套的UI框架Element UI一定是不二之选,平时用Element也比较多,Vue3出来后,Element也正式升级为Element Plus,相比之前的框架,Element Plus采用Vue3的新特性,使用OptionsAPI、TS来重写,并且在之前的基础上加了很多新的组件和特性,而且官方文档也非常详细,按照给出的文档引入框架,使用起来非常顺利,本项目使用文档中的自动导入结合Vite来引入Element Plus框架。

下载Element-Plus╮(‵▽′)╭自动导入插件

# 下载Element Plus包
npm install element-plus --save
# 安装自动导入ElementPlus的两款插件
npm install -D unplugin-vue-components unplugin-auto-import
  • 1
  • 2
  • 3
  • 4

配置vite.config.ts文件

安装好插件后在配置文件中vite.config.ts编写自动导入Element-plus插件的代码。

import { defineConfig, loadEnv } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
// Element-plus自动导入
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';

const pathResolve = (dir: string): any => {
	return resolve(__dirname, '.', dir);
};

const alias: Record<string, string> = {
	'@': pathResolve('./src'),
};

export default defineConfig(({ mode }) => {
	const env = loadEnv(mode, process.cwd());
	return {
		base: env.VITE_PUBLIC_PATH, //配置基础部署路径
		plugins: [
			vue(),
			AutoImport({
				resolvers: [ElementPlusResolver()],
			}),
			Components({
				resolvers: [ElementPlusResolver()],
			}),
		],
		resolve: {
			// 配置路径别名
			alias,
		},
	};
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

按需引入的全局配置

我们使用按需引入的导入方式,那么应该如何调整组件的默认尺寸和语言呢?(ps:官方插件默认配置语言是英语!)官方文档中也有介绍如何配置尺寸和层级,以及如何设置国际化,我们这里需要设置默认语言为中文,组件尺寸和层级使用默认即可。

我们找到根组件App.vue,在顶层组件外面包上elemnt的全局配置注入组件,然后引入框架内置i18n的中文配置,按照下面代码就可以实现组件默认语言为中文了,后面我们会在这个基础上进行修改,结合vue-i18n来实现多语言切换。

<script setup lang="ts">
import zhCn from 'element-plus/lib/locale/lang/zh-cn';
const locale = zhCn;
</script>

<template>
	<el-config-provider :locale="locale">
		<router-view />
	</el-config-provider>
</template>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

关于使用以及自动生成的文件

自动导入图
使用组件很简单,由于配置了自动导入插件,所以可以全局使用插件,我们在LoginView.vue的文件中,将之前的按钮改为element按钮组件,然后保存,之后插件就会自动添加引用到配置文件中(自动生成的文件),由于这两个文件是自动生成的(如上图所示),所以不需要提交到git中,我们在.gitignore文件中将两个文件名配置,不去记录这两个文件,也不需要上传,因为自动导出插件会帮我们生成配置文件,引用了那些组件就会按需加载那些组件配置,添加忽略的两个配置文件如下。

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

## Element自动导入配置文件忽略
auto-imports.d.ts
components.d.ts
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

在使用自动导入插件的过程中,有几个需要注意的地方:

  1. 如果在<template></template>模板内没有使用组件,而在JSX或是TSX中使用了,需要通过import的方式按需引入组件,自动导入插件不会扫描JSX或是TSX代码中的Element组件的。
  2. 如果使用了ElMessage组件或是通知类组件,自动导入插件也不会帮我们导入css样式文件,因为组件自动导入也伴随样式自动导入,所以我们需要在main.ts中添加import 'element-plus/dist/index.css';来完成element的样式导入,这些在TS或JS代码中引用了Element组件却没有自动导入样式就会导致Element组件不能使用或是渲染错误。

vue-i18n的安装与使用

# 国际化插件
npm i vue-i18n
  • 1
  • 2

封装vue-i18n(语言配置)

首先在./src文件夹下面创建一个i18n的文件夹,创建index.ts文件,然后写入下面代码配置。

// ./src/i18n/index.ts
import { createI18n } from 'vue-i18n';
import { themeConfig } from '@/config';
// element-plus 的ui框架国际化语言配置
import zhCnLocale from 'element-plus/lib/locale/lang/zh-cn';
import enLocale from 'element-plus/lib/locale/lang/en';
// 自定义的语言配置
import nextZhCn from './lang/zh-cn';
import nextEn from './lang/en';
// 按照每个页面的语言配置
import loginZhcn from './pages/login/zh-cn';
import loginEn from './pages/login/en';

// 定义语言国际化内容 zh-cn en
const messages = {
	[zhCnLocale.name]: {
		...zhCnLocale,
		ismsg: { ...nextZhCn, ...loginZhcn },
	},
	[enLocale.name]: {
		...enLocale,
		ismsg: { ...nextEn, ...loginEn },
	},
};

export const i18n = createI18n({
	silentTranslationWarn: true,
	missingWarn: false,
	silentFallbackWarn: true,
	fallbackWarn: false,
	locale: themeConfig.value.globalI18n, // 采用全局参数配置初始化语言 项目中有`zh-cn`、`en`两种
	fallbackLocale: zhCnLocale.name,
	messages,
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

其余配置语言文件可以转到项目文件中查看配置,例如自定义的中文配置,我们自定义的语言配置全部设置在ismsg下面,最后合并语言配置导出i18n实例化的对象,然后全局注册国际化插件,将i18n实例注册到vue app实例中。

// ./src/main.ts
import { createApp } from 'vue';
import App from '@/App.vue';
import { i18n } from '@/i18n';

const app = createApp(App);

app.use(i18n)
app.mount('#app');
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

element-plus自动导入组件如何结合vue-i18n?

因为项目中element-plus采用的是按需自动注册组件,网上找了一下没有找到element-plus结合vue-i18n的方法,查看了一下vue-i18n的实例内置方法属性,然后又参照element官网国际化的方法,结合了一下做了如下修改,在根组件使用 ConfigProvider 组件包裹页面入口的<router-view />,这样就可以实现element-plus组件的全局统一默认配置。

代码如下:

<script setup lang="ts">
import { ref, watchEffect } from 'vue';
import { themeConfig } from './config';
import { useI18n } from 'vue-i18n';

// 获取实例
const { messages, locale }: any = useI18n();
const localeLang = ref(messages[themeConfig.value.globalI18n]); // 默认语言

// 修改element 和 i18n 默认语言
const changeLanguage = () => {
	locale.value = themeConfig.value.globalI18n;
	localeLang.value = messages.value[locale.value];
};
// 监听修改语言
watchEffect(changeLanguage);
</script>

<template>
	<el-config-provider :locale="localeLang">
		<router-view />
	</el-config-provider>
</template>

<style>
@import './theme/index.css';
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

themeConfig.value.globalI18n的响应式不能直接作用于i18n的local设置,所以设置了监听属性,如果themeConfig.value.globalI18n发生修改,会触发changeLanguage方法,从而修改element-plus和自定义的国际化语言切换,从而实现通过监听一个变量变更来完成语言切换设置。

全局配置使用响应式的变量结构,目前只有语言设置这一个参数,默认中文。

//  ./src/config/index.js
import { ref, watchEffect } from 'vue';

export const themeConfig = ref({
	// 默认初始语言,可选值"<zh-cn|en>",默认 zh-cn
	globalI18n: 'zh-cn',
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在项目中使用

下面是自定义的语言配置文件

// ./src/i18n/lang/en.ts
export default {
	router: {
		home: 'home',
		docsLink: 'System Docs ',
	},
	header: {
		userCenter: 'Personal Center',
		codeSource: 'Code Warehouse',
		systemGuide: 'System Guide',
		logOut: 'Log Out',
	},
};
// ./src/i18n/lang/zh-cn.ts
export default {
	router: {
		home: '首页',
		docsLink: '系统指南',
	},
	header: {
		userCenter: '个人中心',
		codeSource: '代码仓库',
		systemGuide: '系统指南',
		logOut: '退出登录',
	},
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

$t是i18n注入的一个函数,直接在模板中使用即可,ts脚本中需要使用useI18n获取到t(语言转换函数),或者通过i18n实例下的global属性获取t函数。

在vue文件中使用方法如下:

<script setup lang="ts">
import { useI18n } from 'vue-i18n';
import { i18n } from '@/i18n';
// 获取实例
const { t }: any = useI18n();
// 或者
const t = i18n.global.t;
/* 
  这里为了举例都定义为t
  可以更改为别名,方法如下
  const { t: otherT }: any = useI18n();
  const otherT = i18n.global.t;
 */
// 在脚本中如下方法使用
console.log(t('ismsg.router.home'))
</script>

<template>
	{{ $t('ismsg.router.home') }}
</template>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

本项目编写过程中,在登录页面使用了国际化配置,对于element表单验证提示语采用语言转换时发现失效了,无法转换语言,使用了reactive、ref来定义的rules(表单规则结构),猜测是因为没有对转换函数t实现响应式监听或是响应式失效了,根本原因不太清楚,将reactive或是ref替换为计算钩子函数(computed)即可,然后切换语言的时候提示语也可以正常切换了。

本文可能讲述的不够清晰,只是简单的配置多语言,i18n还有很多种语言替换的方法都没有讲到,可自行查阅博文学习。配置国际化的方法最好自己动手实现一遍,可以结合本项目具体学习,以上讲解所用代码是在项目源码的基础上做了修改而来,具体实现过程可以查看本项目的源代码

结语

本文是基于之前写的集成系统教程而来,后期在项目实践中,对代码还做了许多修改的地方,可能与本文有所出入,但是结合使用的方法本质上还是一样的,本文内容全部基于亲自实践所得,如果对您有帮助,劳烦点赞支持一下作者,如果文章内有错误之处还望指正,希望大家可以共同进步٩(๑❛ᴗ❛๑)۶。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/392368
推荐阅读
相关标签
  

闽ICP备14008679号