关于在自行封装的组件库中(使用vue-class-component)使用Vue-i18n无法正常翻译的解决办法

文章目录

  • 介绍
  • 背景
  • 现象1
    • 解决办法
  • 现象2
    • 原因分析
    • 解决办法
  • 最终方案

介绍

大家或多或少都用过别人封装的组件库,甚至有人或者公司内有自行封装的一些公用组件库,而国际化翻译现在已经是各大项目中必不可少的一个插件了,但组件库中使用 i18n 进行翻译的时候可能遇到过以下这种问题,希望我的一点分析可以帮到你们

背景

因公司历史项目使用 Angular 框架原因,所以在做架构迁移时,我们采用了 vue-class-component(github链接) 和 vue-property-decorator(github链接) 平滑的迁移到了 Vue 框架

部分代码如下:

<template><div class="pager"><span class="grid-pager">{{$t('pager.total', {total: totalRows})}}</span><div class="grid-pager"><a-pagination size="small" v-model:current="index":total="totalRows" v-model:pageSize="size":pageSizeOptions="pageSizeOptions":showSizeChanger="showSizeChanger":showQuickJumper="showQuickJumper":simple="simple"@change="change" /></div></div>
</template><script lang="ts">
import { Options, Vue, setup } from 'vue-class-component';
import { Composer, useI18n } from 'vue-i18n';
import { Emit, Prop, Watch } from 'vue-property-decorator';
@Options({name: 'pager'
})
export default class Pager extends Vue {@Prop({ type: Number, }) public totalRows: number;@Prop({ type: Number, }) public pagerSize: number;@Prop({ type: Number, }) public pageIndex: number;@Prop({ type: Array, default: ['20', '50', '100']}) public pageSizeOptions: Array<number>;@Prop({ type: Boolean, default: false }) public showSizeChanger: boolean;@Prop({ type: Boolean, default: true }) public showQuickJumper: boolean;@Prop({ type: Boolean, default: false }) public simple: boolean;public index: number = 1;public size: number = 20;/*** change事件** @param {number} index 下标* @param {number} size 每页条数* @returns {{index: number, size: number}} 返回分页器当前页码与当前每页条数*/@Emit()public change(index: number, size: number): {index: number, size: number} {return {index: index - 1,size};}/*** 监听 pageIndex 属性变化** @param {number} newValue 新值*/@Watch('pageIndex')public pageIndexChange(newValue: number): void {if (newValue >= 0) {this.index = newValue + 1;}}/*** 监听 pagerSize 属性变化* * @param {number} newValue 新值*/@Watch('pagerSize', { immediate: true })public pageSizeChange(newValue: number): void {if (newValue) {this.size = newValue;}}/*** 钩子函数*/public mounted(): void {if (this.pageIndex || this.pageIndex === 0) {this.index = this.pageIndex + 1;}}
}
</script>
<style lang="scss" scoped></style>

因此我们封装的组件库也是基于此的,若您的项目不是使用该种方式开发的,那我觉得以下部分的内容对您的帮助应该是不多的

同时我们也没有做像现在主流的UI组件库的国际化翻译处理,如 Element UI组件库中既可以兼容 vu-i18n 又可以自行进行翻译(可参考这里)

目前我们只是简单的封装了一个组件到另一个库里,国际化翻译是依赖于本地项目中安装的 vue-i18n 插件进行翻译的,正是因为这个原因才会出现我下面说的情况(后期可能会像组件库一样有自行的翻译方法)

现象1

就以上面的代码为例,若引用该库的项目国际化文件中没有 pager.total 字段时,浏览器控制台就会报错

Not found 'pager.total' key in 'zh_CN' locale messages.

且无法正常翻译
在这里插入图片描述

这是因为在全局国际化翻译文件中没有找到该key值才翻译有误

解决办法

@options 注解中可以直接添加组件级的i18n配置,如下:

@Options({name: 'pager',i18n: {messages: {zh_CN: {'pager.total': '共{total}条'},zh_TW: {'pager.total': '共{total}條'},en_US: {'pager.total': '{total} entries in total'}}}
})

使用这种方式确实可以使用了,因此我们也没多注意,其实它只是在引用这个组件的项目中也使用 vue-class-component 时才可以生效

现象2

基于上面的修改,直到有一天我们有个新的项目使用了 vue3 + vite + setup 技术栈时,它又没有正常翻译了,浏览器控制台报错和现象1一致

然后就是和同事找原因,issue、google都找遍了,没有发现遇到同样问题的,无奈只好自行查阅源码分析原因

原因分析

首先使用 @options 进行注解对象中的内容,会挂载在 Vue实例的 $options 上,如下:
在这里插入图片描述
因此在注解中设置i18n时可以肯定的是可以传给Vue实例的,那么就得看看I18n中是如何处理这部分内容的了(因源码较复杂,以下只关注$options部分)

可以看到这里 就是处理Vue实例上$options的i18n配置的
在这里插入图片描述
可以看到是 这里 引入了该Mixin,因使用的是v9版本,查看 defineMixinNext 调用位置
在这里插入图片描述
可以看到注释以及if判断都明确指出是 Legacy模式下才会进入这部分处理逻辑,那么现在翻译不生效的原因就非常明了了

但是现在本地项目使用的是 Vue3 + Vite + setup suger 技术栈,那么就必选找一个可以兼容的方式呀,不然这组件库不是白封装了吗 (艹皿艹)

然后就是漫长的翻阅 vue-class-component github issue 的过程

解决办法

关注到这个 issue ,里面提到:

Composition functions are available in class property initializers by wrapping setup helper.

也就是说,在V8版本中我们是可以使用 setup 的

而翻阅 Vue-i18n 官网,可以看到在组合式API部分可以在setup中设置组件级的翻译内容
在这里插入图片描述
这样的话,方法就显而易见了,只要在 setup 中设置组件级的翻译内容即可,如下:

public componentSetup = setup(() => {const i18n: Composer = useI18n({locale: 'zh_CN',messages: {zh_CN: {'pager.total1': '共{total}条'},zh_TW: {'pager.total': '共{total}條'},en_US: {'pager.total': '{total} entries in total'}},});return {i18n};
});

结果一试,还是原来的问题,控制台报错,页面没有正常显示,继续翻文档可以看到 这里 提到:
在这里插入图片描述
大致意思就是如果你在 useI18n 中 设置了那些字段时,添加 useScope: 'global' 配置将会将这些字段合并到全局作用域中,这不就是我们想要的吗! (✪ω✪)

public componentSetup = setup(() => {const i18n: Composer = useI18n({locale: 'zh_CN',messages: {zh_CN: {'pager.total1': '共{total}条'},zh_TW: {'pager.total': '共{total}條'},en_US: {'pager.total': '{total} entries in total'}},useScope: 'global'});return {i18n};
});

运行项目并打印全局i18n实例,你会发现组件中的翻译已成功加入全局翻译文件中,且页面也显示正常了
在这里插入图片描述
在这里插入图片描述

最终方案

根据现象1分析得出如果使用 Legacy 模式时可以读取 @Options 注解中的翻译内容
根据现象2分析得出如果使用 Composition 模式时可以读取 setup() 回调中的翻译内容

那么就可以兼容这两种方式使该组件以任何模式引入时都可以正常翻译了,完整代码如下:

<template><div class="pager"><span class="grid-pager">{{$t('pager.total', {total: totalRows})}}</span><div class="grid-pager"><a-pagination size="small" v-model:current="index":total="totalRows" v-model:pageSize="size":pageSizeOptions="pageSizeOptions":showSizeChanger="showSizeChanger":showQuickJumper="showQuickJumper":simple="simple"@change="change" /></div></div>
</template><script lang="ts">
import { Options, Vue, setup } from 'vue-class-component';
import { Composer, useI18n } from 'vue-i18n';
import { Emit, Prop, Watch } from 'vue-property-decorator';
@Options({name: 'pager',// 兼容选项式API模式i18n: {messages: {zh_CN: {'pager.total': '共{total}条'},zh_TW: {'pager.total': '共{total}條'},en_US: {'pager.total': '{total} entries in total'}}}
})
export default class Pager extends Vue {@Prop({ type: Number, }) public totalRows: number;@Prop({ type: Number, }) public pagerSize: number;@Prop({ type: Number, }) public pageIndex: number;@Prop({ type: Array, default: ['20', '50', '100']}) public pageSizeOptions: Array<number>;@Prop({ type: Boolean, default: false }) public showSizeChanger: boolean;@Prop({ type: Boolean, default: true }) public showQuickJumper: boolean;@Prop({ type: Boolean, default: false }) public simple: boolean;public index: number = 1;public size: number = 20;// 兼容组合式API模式public componentSetup = setup(() => {const i18n: Composer = useI18n({locale: 'zh_CN',messages: {zh_CN: {'pager.total': '共{total}条'},zh_TW: {'pager.total': '共{total}條'},en_US: {'pager.total': '{total} entries in total'}},// 将当前翻译内容合并到全局翻译文件中useScope: 'global'});return {i18n};});/*** change事件** @param {number} index 下标* @param {number} size 每页条数* @returns {{index: number, size: number}} 返回分页器当前页码与当前每页条数*/@Emit()public change(index: number, size: number): {index: number, size: number} {return {index: index - 1,size};}
}
</script>
<style lang="scss" scoped></style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1473429.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

计算机网络 0319

OSPF协议&#xff1a;开放式最短路径优先 协议 基于代价的路由协议 适合与大型的网络 DR 指定路由器 BDR 备用指定路由器 OSPF的组播地址 224.0.0.5 224.0.0.6 RIP组播地址&#xff1a;224.0.0.9 OSPF数据包 过程&#xff1a;先各个发送hello包认识&#xff0c;成为邻居…

深圳航空顶象验证码逆向,和百度验证码训练思路

声明(lianxi a15018601872) 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 前言(lianxi a…

CC2530寄存器编程学习笔记_点灯

下面是我的CC2530的学习笔记之点灯部分。 第一步&#xff1a;分析原理图 找到需要对应操作的硬件 图 1 通过这个图1我们可以找到LED1和LED2连接的引脚&#xff0c;分别是P1_0和P1_1。 第二步 分析原理图 图 2 通过图2 确认P1_0和P1_1引脚连接到LED&#xff0c;并且这些引…

51单片机———LED点阵屏显示图形动画

单片机上的一小块屏幕就是LED点阵屏&#xff0c;与数码管一样&#xff0c;内部由LED灯组成&#xff0c;只是点阵屏使用的LED灯更多&#xff0c;LED灯呈矩形分布而非“8”字形&#xff1b;并且点阵屏和数码管一样&#xff0c;有两种接法共阳极和共阳极&#xff1b; 16*16LED点阵…

springboot集成tika解析word,pdf,xls文件文本内容

介绍 Apache Tika 是一个开源的内容分析工具包&#xff0c;用于从各种文档格式中提取文本和元数据。它支持多种文档类型&#xff0c;包括但不限于文本文件、HTML、PDF、Microsoft Office 文档、图像文件等。Tika 的主要功能包括内容检测、文本提取和元数据提取。 官网 https…

vite+vue3整合less教程

1、安装依赖 pnpm install -D less less-loader2、定义全局css变量文件 src/assets/css/global.less :root {--public_background_font_Color: red;--publicHouver_background_Color: #fff;--header_background_Color: #fff;--menu_background: #fff; }3、引入less src/main.…

【postgresql】版本学习

PostgreSQL 17 Beta 2 发布于2024-06-27。 PostgreSQL 17 Beta 2功能和变更功能的完整列表&#xff1a;PostgreSQL: Documentation: 17: E.1. Release 17 ​ 支持的版本&#xff1a; 16 ( 当前版本) / 15 / 14 / 13 / 12 ​ 不支持的版本&#xff1a; 11 / 10 / 9.6 / 9.5 /…

WEB04MyBatis

Mybatis mybatis查询 准备 准备工作 在目前的数据库中添加一张数据表emp 将资料中提供的day04-01-mybatis导入的目前的工程中 修改配置文件中的数据库的账户和密码 观察实体类中的属性和数据表中的字段的对应关系 查询结果封装 查询所有 SQL语句 select * from emp; …

深度解析Ubuntu版本升级:LTS版本升级指南

深度解析Ubuntu版本升级&#xff1a;Ubuntu版本生命周期及LTS版本升级指南 Ubuntu是全球最受欢迎的Linux发行版之一&#xff0c;其版本升级与维护策略直接影响了无数用户的开发和生产环境。Canonical公司为Ubuntu制定了明确的生命周期和发布节奏&#xff0c;使得社区、企业和开…

【MySQL04】【 redo 日志】

文章目录 一、前言二、redo 日志1. redo 日志格式2. Mini-Transaction2.1 以组的形式写入 redo 日志2.2 Mini-Transaction &#xff08;MTR&#xff09;概念 3. redo 日志写入过程3.1 redo 日志缓冲区3.3 redo 日志写入 log buffer 4. redo 日志文件4.1 redo 日志刷盘机制4.2 r…

2024年江苏省研究生数学建模竞赛B题人造革性能优化设计研究论文和代码

经过不懈的努力&#xff0c; 2024年江苏省研究生数学建模竞赛B题人造革性能优化设计研究论文和代码已完成&#xff0c;代码为C题全部问题的代码&#xff0c;论文包括摘要、问题重述、问题分析、模型假设、符号说明、模型的建立和求解&#xff08;问题1模型的建立和求解、问题2模…

HCIA综合实验

学习新思想&#xff0c;争做新青年。今天学习的是HCIA综合实验&#xff01; 实验拓扑 实验需求 总部&#xff1a; 1、除了SW8 SW9是三层交换机&#xff0c;其他交换机均为2层交换机。 2、GW为总部的出口设备&#xff0c;使用单臂路由技术&#xff0c;VLAN10,20,100的网关都在GW…

Positron初尝试,新一代数据科学IDE(R+Python+...)

Introduction Positron&#xff08;正电子&#xff09;&#xff0c;是由 RStudio 母公司&#xff08;改名叫 Posit&#xff09;构建的下一代数据科学 IDE&#xff0c;一个可用于编写代码和探索数据的可扩展的多语言工具&#xff0c;并提供可重复创作和发布的熟悉环境。 主页&…

基于SpringBoot的校园台球厅人员与设备管理系统

本系统是要设计一个校园台球厅人员与设备管理系统&#xff0c;这个系统能够满足校园台球厅人员与设备的管理及用户的校园台球厅人员与设备管理功能。系统的主要功能包括首页、个人中心、用户管理、会员账号管理、会员充值管理、球桌信息管理、会员预约管理、普通预约管理、留言…

中英双语介绍英国伦敦(London)

中文版 伦敦简介 伦敦&#xff08;London&#xff09;是英国的首都&#xff0c;也是全球最重要的金融、文化、艺术和交通中心之一。作为一座历史悠久的城市&#xff0c;伦敦融合了现代化的城市生活与丰富的历史遗产。以下是对伦敦的详细介绍&#xff0c;包括其经济状况、高等…

Pandas 入门 15 题

Pandas 入门 15 题 1. 相关知识点1.1 修改DataFrame列名1.2 获取行列数1.3 显示前n行1.4 条件数据选取值1.5 创建新列1.6 删去重复的行1.7 删除空值的数据1.9 修改列名1.10 修改数据类型1.11 填充缺失值1.12 数据上下合并1.13 pivot_table透视表的使用1.14 melt透视表的使用1.1…

【学术会议征稿】第四届先进算法与神经网络国际学术会议(AANN 2024)

第四届先进算法与神经网络国际学术会议&#xff08;AANN 2024&#xff09; 2024 4th International Conference on Advanced Algorithms and Neural Networks 第四届先进算法与神经网络国际学术会议&#xff08;AANN 2024&#xff09;由中国石油大学&#xff08;华东&#x…

解决使用PPIO欧派云服务器时无法使用sftp的问题

首先在对外TCP端口中选择22端口&#xff1a; 在连接-端口映射中可以看到&#xff1a; 使用ssh连接云服务器&#xff0c;更新包列表并安装OpenSSH服务器&#xff1a; apt-get update apt-get install-y openssh-server 创建 SSH 运行目录&#xff1a; mkdir /var/run/sshd 设…

Xilinx原语

1. 原语介绍 原语是 Xilinx 器件底层硬件中的功能模块&#xff0c;它使用专用的资源来实现一系列的功能。相比于 IP 核&#xff0c;原语的调用方法更简单&#xff0c;但是一般只用于实现一些简单的功能。本章主要用到了 BUFG、 BUFIO、 IDDR、 ODDR、IDELAYE2 和 IDELAYCTRL。…

【算法 - 哈希表】两数之和

这里写自定义目录标题 两数之和题目解析思路解法一 &#xff1a;暴力枚举 依次遍历解法二 &#xff1a;使用哈希表来做优化 核心逻辑为什么之前的暴力枚举策略不太好用了&#xff1f;所以&#xff0c;这就是 这道题选择 固定一个数&#xff0c;再与其前面的数逐一对比完后&…