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


    前言

    之前就想使用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. 如果在模板内没有使用组件,而在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 组件包裹页面入口的,这样就可以实现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
    	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还有很多种语言替换的方法都没有讲到,可自行查阅博文学习。配置国际化的方法最好自己动手实现一遍,可以结合本项目具体学习,以上讲解所用代码是在项目源码的基础上做了修改而来,具体实现过程可以查看本项目的源代码

    结语

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

  • 相关阅读:
    web前端-html-css-HACK(CSS Hack 实际上指的就是一个特殊的代码,这段代码只在某些特殊的浏览器中可以识别)
    Linux 文件权限的修改
    2024北京国际物联网展览会(物联网展)物物相连,万物互联
    近期面试128题汇总(有超详细答案)
    云原生之Kubernetes:17.详解Apiserver和RBAC
    TensorRT开发环境搭建
    数学建模 -- 灰色预测模型
    UE5 GAS 学习笔记 后记0
    Docker-Cgroup
    AWS SAA-C03 #101
  • 原文地址:https://blog.csdn.net/qq_42476927/article/details/126875343