Vue3专栏项目 -- 二、自定义From组件(下)

需求分析:

现在我们还需要一个整体的表单在单击某个按钮的时候可以循环的验证每个input的值,最后我们还需要有一个事件可以得到最后验证的结果,从而进行下一步的操作

如下,我们应该有一个form表单包裹着全部的input表单;然后有一个提交按钮;点击这个按钮触发一个事件去验证包裹的这些input,从而获取验证的结果。

这里有一个难点就是获取每一个input的验证结果。

一、ValidateForm编码 - 使用插槽slot(实现所有input都在form表单中)

如下我们创建好了基本结构后

用插槽实现相对应样式

我们是在该组件内添加自定义的内容,那么我们想到之前Dropdown下拉菜单栏组件的slot插槽,当时下拉菜单的‘新建文字’‘编辑资料’‘退出登录’我们是怎么做的呢。我们建一个DropdownItem组件是一个新建文字的一个选项的组件,在该组件中用插槽占位,Dropdown也是用插槽占位,然后我们在GlobalHearder标题组件组件中想要多少个下拉选项就直接在DropdownItem中插入即可,插入的这些DropdownItem们就是插入到Dropdown的。如下,这种就可以想要多少个选项就直接在GlobalHearder中加入即可,这样不限定DropdownItem插入多少也不限定Dropdown插入多少,插入多少都可以

但是和之前这个稍微不同的呢,是我们的插槽其实分为2块区域,一块是这个input表单,一块是提交按钮的区域,不传任何内容的时候它会渲染一个默认的按钮,就等于其实我们有两个可以自定义的插槽,我们去文档看看这种方法应该怎么实现,如下通过添加name的方式

如下我们就填入了两个具名插槽

我们到App.vue中导入感受一下

如下我们使用一个叫template的元素,template上有一个属性叫v-slot,这个v-slot指令就是组件内部定义的这个模板名称,它就等于这个submit,那个name为submit的插槽。也可以用缩写:#submit 也是一样的

然后我们做点击提交按钮发送事件。

在子组件中点击按钮,点击事件发送后,在父组件中监听结果。

首先我们要在emit字段里面确定我们要发送的这个自定义事件的名称,之前我们都是使用Object定义它,其实如果没有这个事件的验证,也可以使用数组来定义要触发的事件,我们事件这里就叫form-submit

那么这个事件什么时候触发呢,我们可以给这个submit-area上面添加一个click事件叫submitForm,然后这个点击事件中通过context.emit('form-submit',true)来触发它

然后我们到父组件中监听结果。我们创建一个函数来监听结果,如下定义一个函数叫onFormSubmit,然后在这个子组件标签中通过@form-submit="onFormSubmit"即可

如下,我们定义一个onFromSubmit的函数,子组件那个点击事件中触发的就是父组件中这个事件,这个事件中我们打印一下获取的参数。

如下,点击按钮后,控制台打印出传过来的值了

二、ValidateForm编码 - 尝试父子通讯(在form组件中获取input组件中验证方法返回的值)

现在我们来做在form中完成所有input的验证。

要想在父组件中访问子组件的方法,那么我们就必须拿到这个方法,并且调用,那么怎样拿到一个组件的实例呢,就是说你怎么在父组件App.vue中拿到子组件ValidateInput.vue中的实例(实例即有这个子组件的所有属性、方法)

我们之前获取dom节点,使用了ref这个属性,即在这个dom节点中添加这个ref。那么当这个ref属性不是添加到一个节点上,而是添加到一个自定义组件上又会发生什么有趣的事呢。

如下,我们在父组件App.vue的setup中定义一个ref响应式的变量叫inputRef,然后在子组件validate-input的标签中加上ref="inputRef",然后通过inputRef.val就可以获取这个子组件validate-input的实例,我们在点击事件即onFormSubmit中打印出这个实例

如下可以看到,这个Proxy对象中的这些属性和方法都是子组件validateinput组件的属性和方法,即我们成功获得了子组件的实例对象。我们是想得到验证的input的结果,也就是我们想在父组件中获得validateInput组件中验证表单的方法validateInput返回的结果,结果是验证为true还是false。这种方法我们可以获取子组件实例,也就是我们就可以获得子组件某方法返回的结果。

如上,子组件验证规则这个方法中返回验证结果,然后我们在父组件中通过inputRef.value.validateInput()即可获取到子组件中这个验证方法,如此父组件中即可拿到子组件中验证方法返回的结果了

那这种做法可以在validateForm中使用吗,也就是说我们想在validateForm组件中也获取validateInput组件的验证方法的返回值。

来看validateForm的结构,这时候发现这里没有validate-input标签,变成了slot标签,而这个slot占位符可能有多个validate-input,我们没法用一个变量或者数组来定义它即像上面那样定义一个响应式变量,而且slot也不支持ref属性,那么就无法像上面那样通过定义一个响应式变量,然后在标签中通过ref="这个响应式变量",然后通过这个响应式变量.value来获得这个validateInput组件的实例。

那怎么办呢,那么这个通过ref获取另一个组件实例的方法走不通了,我们就需要其他的一种父组件和子组件通讯方式。

由于slot的特殊性,这时候我们就需要事件监听器来帮忙了。

我们在父组件validate-form中创建一个事件监听器,去监听相应的事件;然后在子组件validate-input中通过某种方法往这个监听器里面手动触发事件,把想要的内容传递过去

我们来想想应该怎么实现

首先我们应该在父组件即validateForm中创建事件监听,也就是this.$on(事件名称A,传过来的函数)创建一个事件监听,然后创建一个数组为空,该函数就把子组件传过来的函数一个个放到数组中;

然后在子组件即validateItem中我们怎么拿到父组件这个事件呢,其实有一个神奇的属性称为$parent,这个$parent可以用来从一个子组件直接访问父组件的实例,所以我们在子组件中通过this.$parent.emit('A',validateInput验证函数),就可以实现在子组件中获取父组件的事件监听函数,同时把子组件的验证函数发过去。

假如email这个item被初始化的时候,email的validateChange函数就会被加到数组中,password这个item被初始化的时候,password的validateChange函数就会被加到数组中,最后在父组件中循环调用这个方法就可以看到每个子组件的执行结果了

接下来我们编码

由于this在setup中无法访问,所以我们先用这个vue2方法创建,如下,发现说vue3中关于这个事件的这三个$on、$off、$once已经被放弃,推荐mitt

三、ValidateForm编码 - 寻找外援mitt

可以看到mitt是一个流行的库

如下可以看到它的API有如下

首先我们来安装它 npm install --save mitt,然后在validate-form组件中引入这个mitt

然后我们到validate-form组件中创建一个事件监听器,并且监听相应的事件。

我们在它用法中可以看到我们直接调用mitt() 函数就可以创建监听器了

所以如下创建监听器mitt(),因为我们要把这个监听器给validate使用,所以我们要把它导出去

然后现在是有了监听器,然后我们定义监听事件callback,然后我们通过emitter.on()把这个监听事件添加到监听器中,注意在组件销毁阶段记得把创建的监听器销毁

现在这个监听器已经设置完毕,它像一个收音机一样正在等待接收信号,现在让我们到validateInput组件中向它发动信息

首先我们要把监听器导入进validateInput组件中,然后在组件onmounted后就可以把信息发送出去了。

如下,我们在onmounted中向监听器中发送东西了

如下,validateInput那边onmounted中把inputRef.val值传给名叫form-item-created的监听器中了,监听器监听到有信息来了,就去触发绑在它身上的这个callback函数并且把传过来的inputRef.val值这个值传给这个callback,该函数中打印出传过来的值

所以如图,控制台中就打印出了validateInput中传过来的输入框的值

这就说明了我们在form中设立的电台成功的收到了input的信号,那我们就成功在两个组件中打通了沟通的桥梁,当然通过这种方法可以发送各种内容,而不仅仅是这个val字符串。

这样我们就实现了子组件向父组件传东西的想法,这样下面子组件把验证函数或者说验证结果传给父组件就行得通了

四、ValidateForm - 传递子组件的验证函数给父组件

子组件向父组件发送子组件中真实的验证函数。

所以validateInput组件中这里应该传入validateInput函数

然后validateForm中应该接,首先我们定义一个空数组,用来放置子组件validateInput传过来的验证函数,这些函数执行以后可以显示错误的信息并且返回input是否通过验证,所以我们要给它一个简单的定义,如下,定义一个类型ValidateFunc是一个函数,返回的是布尔值

然后最重要的一步,就是在这个submitForm即提交事件中,循环执行funcArr数组中传过来的这些验证函数,并且返回所有结果的最终值,并且最后通过这个事件发送出去。

循环调用一系列方法并且最终返回一个布尔,当有一个返回false,那么说明里面有错误,那么整个表单的验证就没有通过,那么就想到了用every方法。

但是当你用every()方法去执行funcArr数组中传过来的这些验证函数时,会发现如果输入框都为空,点击提交,发现只执行了一个验证函数,即只有一个input框显示出不能为空的提示。

这是因为类似every()、some() 这些Array上面的方法,它会提前停止循环,当我们里面有一个验证函数返回false时,所以最终结果就是false,所以它很聪明就不再执行后面的函数就直接返回false了节省代码执行时间,而这不是我们想要的,因为后面的验证函数不执行的话,就无法弹出后面输入框‘不能为空’的提示

所以我们需要运行数组里面的所有函数,然后再去判断是否通过。这时候我们就把every改为map,改成map后会生成一个运行函数以后最终生成一个布尔数组,所以map(func=>func)就生成了一个装满布尔值的数组,然后我们再使用every就可以解决,every就去判断这些布尔值中有没有false即可

如下,得到所有input组件中的验证函数后都存放在一个数组中,然后遍历执行这个数组中的所有函数,然后得到所有input是否全部通过验证的结果即result,最后这个result被传回到了父组件App.vue中

这样就实现了,form组件中获取全部input组件的验证结果,然后判断出整个是否通过验证,并且整个form组件是否通过验证的结果还传回了App.vue组件中

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

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

相关文章

视频批量剪辑高效掌握,轻松驾驭视频制作,播放速度与帧数尽在掌控

在追求速度与激情的视频制作世界里,你是否曾渴望拥有一款能够轻松调整播放速度和秒数的神器?现在,这款神器已经来到了你的身边,让你在视频制作的道路上更加得心应手,效率倍增! 首先,我们要进入媒…

【密评】 | 商用密码应用安全性评估从业人员考核题库(8/58)

国家支持社会团体、企业利用自主创新技术制定()国家标准、行业标准相关技术要求的商用密码团体标准、企业标准。 A.低于 B.等于 C.高于 D.相当于 在密码的实际应用中,通常使用下列哪种方法来实现不可否认性()。 A.加密…

【Python 下载大量品牌网站的图片(二)】关于图片的处理和下载,吃满带宽,可多开窗口下载多个网站,DOS窗口类型

写作日期:2024.05.11 使用工具:Python 可修改功能:线程量、UA、Cookie、代理、存储目录、间隔时间、超时时间、图片压缩、图片缩放 默认功能:图片转换、断续下载、图片检测、路径处理、存储文件 GUI:DOS窗口 类型&…

win11 安装oracle11g详细流程及问题总结

1.安装包下载地址 本案例操作系统, Oracle 11g下载-Oracle 11g 64位/32位下载官方版(附详细的安装图解教程) - 多多软件站多多为大家免费提供Oracle 11g下载,包含64位/32位官方版本,并附详细的Oracle 11g安装图解教程,同时希望能…

谷歌外链怎么发?

既要数量也要质量,要保证你的链接广泛分布,在数量上,确实需要你的链接在各种平台上有所展现,这样能提升你网站的知名度和曝光率,但是,光有数量是不够的,如果这些链接的内容不行,那对…

【ZZULI数据结构实验】压缩与解码的钥匙:赫夫曼编码应用

📃博客主页: 小镇敲码人 💚代码仓库,欢迎访问 🚀 欢迎关注:👍点赞 👂🏽留言 😍收藏 🌏 任尔江湖满血骨,我自踏雪寻梅香。 万千浮云遮碧…

发散式变化、霰弹式修改和单一职责

“发散式变更与霰弹式修改之间的精妙点:单一职责(SRP:Single responsibility principle)” 本文适合以下小伙伴们观看: 遇到过问题:只改一个小功能,却需要修改一堆分散在各处的代码,有时还会漏改遇到过问题&#xff…

linux打包流程

因为linux有俩个python版本,我们需要切换到python3这个版本,默认是python 2.7 alias pythonpython3 切换到python3 再次执行:python -V 显示出python的版本了,然后查看pip的配置,我们打包里面需要的第三方需要放到pip…

【C#进阶】简单数据结构类

简单数据结构类 文章目录 1、Arraylist1、ArrayList的本质2、声明3、增删查改4、装箱拆箱思考 背包售卖 2、Stack1、Stack的本质2、声明3、增取查改4、遍历思考 计算一个数的二进制 3、Queue1、Queue的本质2、声明3、增取查改4、遍历思考 每隔一段时间打印一条消息 4、Hashtab…

腾讯共享WiFi项目的加盟方式有哪些?

在这个互联互通的时代,共享经济的浪潮正以前所未有的力量席卷全球,而腾讯作为中国互联网巨头之一自然不会错过这场盛宴。其推出的腾讯共享WiFi项目自问世以来就备受瞩目,它不仅为用户提供便捷的上网服务,更为创业者打开了一个全新…

ModuleSim 仿真找不到模块 module is not defined

提示如下: # vsim -t 1ps -L altera_ver -L lpm_ver -L sgate_ver -L altera_mf_ver -L altera_lnsim_ver -L cycloneive_ver -L rtl_work -L work -voptargs""acc"" pulse_generator_tb # Start time: 14:26:25 on May 10,2024 # ** Note: (…

【全部更新】2024数维杯A题完整成品代码文章思路结果分享

A题 多源机会信号建模与导航分析 摘要 全球卫星定位系统(GPS)虽广泛应用于全球定位与导航,但其在室内、隧道以及建筑密集区等复杂环境中的有效性受限。为解决这一局限性,本研究探讨了一种基于机会信号的自主定位导航方法。 机会信…

一文看懂第三方支付账户体系

什么是账户? 账户是根据会计科目设置的,具有一定格式和结构,用于分类反馈会计要素增加变动情况及其结果的载体。设置账户是会计核算的重要方法之一。 同会计科目分类相对应,账户按其提供的信息详细程度和统驭关系不同分为总账账户…

ICRA 2024 成果介绍:基于 RRT* 的连续体机器人高效轨迹规划方法

近来,连续体机器人研究受到越来越多的关注。其灵活度高,可以调整形状适应动态环境,特别适合于微创手术、工业⽣产以及危险环境探索等应用。 连续体机器人拥有无限自由度(DoF),为执行空间探索等任务提供了灵…

sssadsa

目录 Baidu Comate的功能安装流程功能特性 代码生成代码解释代码补充代码注释智能问答 总结 Baidu Comate: 智能编程助手 在人工智能的驱动下,开发者的编程体验正发生天翻地覆的变化。技术的革新和突破带来的是更智能、高效的工具。Baidu Comate智能代码助手&…

【Vue】Vue的核心

目录 计算属性-computed插值语法实现methods实现计算属性实现使用使用总结: 监视属性-watch监视的两种写法:深度监视备注: computed和watch之间的区别 绑定样式class样式绑定字符串写法数组写法对象写法 style样式绑定对象式1对象式2数组式 条…

汗之谜语,流产之哀:肾合唤醒生命花园的璀璨绽放

在这个疾驰的时代洪流中,女性宛若四季更迭间绚烂绽放的花朵,她们在风雨的锤炼与暖阳的抚慰下,演绎着生命的绚烂篇章。但当这份细腻柔美的内在花园偶遇冷冽寒潮,诸如汗水的异常涌动与生命的意外流失,就如同春暖花开之际…

Wallace树乘法器及Verilog实现

一、Wallace树乘法器 Wallace树乘法器就是将多个部分积进行分组,每三个一组,最后如果剩下的部分积个数不够三个的不做处理,然后将各组的部分积进行相加得到和以及进位信息,直到最终只剩下两行部分积,相加后得到最终结…

界面组件DevExpress Reporting中文教程 - 标记(可访问)PDF导出增强

DevExpress Reporting是.NET Framework下功能完善的报表平台,它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集,包括数据透视表、图表,因此您可以构建无与伦比、信息清晰的报表。 可访问性支持在DevExpress这里仍然是一个高优先…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 5月11日,星期六

每天一分钟,知晓天下事! 2024年5月11日 星期六 农历四月初四 1、 央行新信号:统筹研究消化存量房产和优化增量住房的政策措施。 2、 民政部等七部门规范养老机构预收费:预收周期不得超12个月。 3、 气象局:南方将迎新…