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

news2024/11/24 1:42:17

需求分析:

现在我们还需要一个整体的表单在单击某个按钮的时候可以循环的验证每个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://www.coloradmin.cn/o/1660830.html

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

相关文章

分布式模式让业务更高效、更安全、更稳定

​🌈 个人主页:danci_ 🔥 系列专栏:《设计模式》 💪🏻 制定明确可量化的目标,坚持默默的做事。 🚀 转载自热榜文章🔥:探索设计模式的魅力:分布式模…

ICode国际青少年编程竞赛- Python-4级训练场-while语句入门

ICode国际青少年编程竞赛- Python-4级训练场-while语句入门 1、 while Flyer.disappear():wait() Dev.step(2)2、 Dev.step(1) while Flyer.disappear():wait() Dev.step(5)3、 while Flyer[0].disappear():wait() Dev.step(3) Dev.step(-1) while Flyer[0].disappear():…

VM虚假机联网(无代码,超简单)NAT模式

1、左边顶上编辑里面最下面找到虚拟网络编辑器2.启用管理员特权3.重新创建一个NAT模式的网络(名称随便一个) 4.打开这两个设置里面的东西进行拍照并记住IP区间和网关,等下要用; 5.打开虚拟机,右上角,下标点…

万物生长大会 | 创邻科技再登杭州准独角兽榜单

近日,由民建中央、中国科协指导,民建浙江省委会、中国投资发展促进会联合办的第八届万物生长大会在杭州举办。 在这场创新创业领域一年一度的盛会上,杭州市创业投资协会联合微链共同发布《2024杭州独角兽&准独角兽企业榜单》。榜单显示&…

怎么用照片制作gif动图?一个网站在线做

在数字图像处理中,动态图片是我们日常生活中不可缺少的一部分。Gif动图以为器画面展示的形式,文件的体积以及兼容性而备受喜爱。通过使用多张照片制作gif动画的操作,可以让我们制作出生地有趣的gif动态效果,能够更好更快的传达信息…

谈基于ATTCK框架的攻击链溯源

引言 网络安全在当今数字化时代变得尤为关键,而MITRE公司开发的ATT&CK框架则成为了安全专业人员的重要工具。ATT&CK是一种广泛使用的攻击行为分类和描述框架。其目的在于提供一个共同的语言,使安全专业人员能够更好地理解攻击者的行为和目标&…

【vue-echarts】 报错问题解决 “Error: Component series.pie not exists. Load it first.“

目录 问题描述解决【解决1】【解决2】 问题描述 使用 vue-echarts 时导入的文件 import VChart from vue-echarts/components/ECharts import echarts/lib/chart/line import echarts/lib/chart/bar import echarts/lib/chart/pie import echarts/lib/component/legend impor…

张艺凡闪耀的星光真实的魅力

张艺凡:闪耀的星光,真实的魅力在浩瀚的娱乐圈中,总有那么一些名字,能够点燃我们的热情,让我们为之倾倒。今天,我们要聊的,就是那位一见倾心、再见依然动心的张艺凡。当“张艺凡被夸漂亮”的话题…

机器学习的一些知识点分享

下面数据集中,第2个样本的第4个属性的值是( )。 A 52 B 男 C 50 D 49 本题得分: 2分 正确答案: D 2.单选题 (2分) 10-折交叉验证是把数据集分成( )个子集,将其中&#xff…

数据结构--顺序表和链表的区别

顺序表和链表之间各有优劣,我们不能以偏概全,所以我们在使用时要关注任务的注重点,以此来确定我们要使用两者中的哪一个。 不同点: 存储空间上: 顺序表在物理结构上是一定连续的,而链表(这里以带头双向循环…

读取打包到JAR中的文件:常见问题与解决方案(文件在但是报错not find)

读取打包到JAR中的文件:常见问题与解决方案 喝淡酒的时候,宜读李清照;喝甜酒时,宜读柳永;喝烈酒则大歌东坡词。其他如辛弃疾,应饮高梁小口;读放翁,应大口喝大曲;读李后主…

【Python爬虫实战入门】:教你一个程序实现PPT模版自由

文章目录 💥一、PPT模版爬取🔥1.1 第一个爬虫🚲1. 获取下载页面链接 ❤️1.2 第二个爬虫🚲1.3 第三个爬虫🎈2. 文件保存 ❤️1.4 翻页处理 🔥二、完整代码 🔥🔥🔥 Pytho…

双向链表(详解)

在单链表专题中我们提到链表的分类,其中提到了带头双向循环链表,今天小编将详细讲下双向链表。 话不多说,直接上货。 1.双向链表的结构 带头双向循环链表 注意 这几的“带头”跟前面我们说的“头节点”是两个概念,实际前面的在…

【神器来袭】快速解放双手,朋友圈自动转发工具,告别繁琐操作!

朋友圈作为一个重要的营销推广渠道,如果能实现自动转发,那对于很多企业或个人来说,是极好的。下面,就给大家分享一个实用且便捷的朋友圈运营工具——个微管理系统,让大家都能快速推广。 1、多账号登录,定时…

bcrypt.dll文件丢失怎么办?bcrypt.dll怎么修复?

在计算机系统运行过程中,如果发现无法找到或缺失bcrypt.dll文件,可能会引发一系列的问题与故障。首先,由于bcrypt.dll是系统中一个重要的动态链接库文件,它的主要功能可能涉及到系统核心服务、应用程序支持或者特定功能模块的运行…

python爬虫(三)之虎嗅网汽车文章爬虫

python爬虫(三)之虎嗅网汽车文章爬虫 闲来没事,闲鱼上有个好兄弟要我从虎嗅网上抓一些汽车文章的爬虫,于是大力出奇迹,我写了一个python程序,将这个网站上所有的汽车文章全部抓取下来了,存储到…

2024年记一次Mingw64-13.2.0编译Qt6.6.3,包含文档编译。

My C Development. 前言:不包含qtwebengine。 一、准备文件 (1)mingw64-13.2.0 下载链接:,ucrt64_13.2_ucrt_posix_rev6_msys2.7z【蓝奏云】。 (2)qt6.6.3源码 下载链接:Downlo…

电子版图书制作,一键转换可仿真翻页的画册

在数字化浪潮的冲击下,传统纸质图书逐渐被电子版图书取而代之。电子版图书以其便携、环保、更新快速等特点,吸引了越来越多的读者。制作一款既具备电子图书的便捷性,又能仿真翻页的画册,成为当下图书出版行业的新趋势 1.要制作电子…

微信小程序支付(完整版)-ThinkPHP/Uniapp

技术说明 1.前端:uniapp、vue3 2.接口:PHP8、ThinkPHP8、MySQL8.0 3.微信支付- PHP,官方示例文档 4.示例代码的模型及业务自己进行调整,不要一味的复制粘贴!!! 流程说明 1.小程序调用接口…

资源管理游戏模版进入The Sandbox

我们非常高兴地向您介绍 Game Maker 的最新模板:资源管理游戏! 这一全新的模板让您能够深入身临其境的游戏体验中,同时掌握令人兴奋的新机制。通过揭开模板的神秘面纱,您可以锤炼您的游戏设计技能。 什么是资源管理游戏&#xff1…