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://www.mfbz.cn/a/612005.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】整数和浮点数在内存中的存储

大家可能在学习的时候会经常疑惑数据在内存中是怎样存储的,今天用一篇博客给你讲清楚!!!从此不再疑惑!!! 文章目录 1. 整数在内存中的存储2. 大小端字节序和字节序判断2.1 什么是大小端2.2 为什…

[VulnHub靶机渗透] Hackademic: RTB1

🍬 博主介绍👨‍🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收…

day2_greedyIntervalsLRU/LFU

二、贪心算法之区间调度问题 0.计算一个区间集合中无重复的区间的最大数量(模板) public int intervalSchedule(int[][] intvs) {if (intvs.length 0) return 0;// 按 end 升序排序Arrays.sort(intvs, (a, b) -> Integer.compare(a[1], b[1]));// 至少有一个区间不相交in…

Baidu Comate 编程插件:提升开发效率的利器

文章目录 引言简介目的 Baidu Comate插件概述定义与功能市场现状竞品分析 安装与配置VsCode 安装:注意事项 版本选择 核心特性详解功能介绍代码生成实时续写错误纠正 使用体验体验地址 引言 简介 基于文心大模型,结合百度积累多年的编程现场大数据和外…

专业做护眼灯的有哪些品牌?几款专业儿童卧室灯品牌分享

在当今时代,我们观察到一个不容忽视的现象:孩子们的视力问题日益增多,这无疑向众多家长发出了警示。它提醒着我们,除了追求学术成就之外,孩子们的视觉健康同样重要,不容忽视。因此,选择一款适合…

leetcode刷题:对称二叉树

题目: 给你一个二叉树的根节点 root , 检查它是否轴对称。 示例 1: 输入:root [1,2,2,3,4,4,3] 输出:true 示例 2: 输入:root [1,2,2,null,3,null,3] 输出:false 提示&#xf…

以导航产品为核心,东软想为车企扫除出海障碍

得益于新能源汽车领域多年的布局,以及在汽车智能化方面的先发优势,近年来,中国汽车品牌在质与量上都得到了极大提升,并带来强大的竞争力。 据海关总署公布的数据,过去三年,中国汽车出口规模连续突破式发展…

LeetCode算法题:7. 整数反转

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。 如果反转后整数超过 32 位的有符号整数的范围 [−2^31, 2^31 − 1] ,就返回 0。 假设环境不允许存储 64 位整数(有符号或无符号)。 示例 1: 输…

会赚钱的人都在做这件事:你了解吗?

在我们日常生活的点滴中,以及在各种场合的交互中,利他思维始终扮演着不可或缺的角色。当我们追求合作与共赢时,单方面的自我立场显然是不够的,真正的关键在于换位思考,寻找并满足对方的需求。 互利互赢的核心理念正是利…

【挑战30天首通《谷粒商城》】-【第一天】【10 番外篇】 解决docker 仓库无法访问 + MobaXterm连接VirtualBox虚拟机

文章目录 课程介绍 1、解决docker 仓库无法访问 2、 MobaXterm连接VirtualBox虚拟机 Stage 1:下载MobaXterm选择适合你的版本 Stage 2:vagrant ssh 连接,开启ssh访问 Stage 2-1:su获取root账号权限,输入密码(默认vagra…

纯血鸿蒙APP实战开发——阅读翻页方式案例

介绍 本示例展示手机阅读时左右翻页,上下翻页,覆盖翻页的功能。 效果图预览 使用说明 进入模块即是左右翻页模式。点击屏幕中间区域弹出上下菜单。点击设置按钮,弹出翻页方式切换按钮,点击可切换翻页方式。左右翻页方式可点击翻…

【软件测试】3.开发模型

目录 1.常见的开发模型 1.1瀑布模型 1.2螺旋模型 1.3增量模型和迭代模型 1.4敏捷模型 1.4.1特点: 1.5Scrum模型(三个角色和五个重要会议) 1.5.1三个角色: 1.5.2Scrum工作流程(五个会议) 1.6测试模…

如何选择适合自己网站的SSL证书提供商?

在互联网技术飞速发展的今天,确保数据安全已成为网站运营的基石。HTTPS证书作为一项重要的安全认证协议,对于保护数据传输的安全性至关重要。本文将为您提供一份详尽的指南,帮助您了解如何申请和部署HTTPS证书。 一、选择SSL证书提供商 首先…

JUC下的CompletableFuture详解

详细介绍 CompletableFuture是Java 8引入的一个实现Future接口的类,它代表一个异步计算的结果。与传统的Future相比,CompletableFuture提供了更丰富的功能,比如链式调用、组合异步操作、转换结果、异常处理等,极大地增强了Java在…

给网络镜像模式下的 WSL2 使用 127.0.0.1代理的方法

网络镜像模式下的WSL2虽然复制了宿主机windows的ip,但是仍然无法访问127.0.0.1的代理。经过调查,发现因为WSL2从应用商店下载而来,所以可能是UWP应用,所以需要用工具解除环回代理限制。

mysql 不停的重启关闭

早上在使用phpstudy的时候,发现自己的mysql5.7和5.8都出现了问题,就是不停的重启,在梳理了状况之后,可能是硬盘的内存空间不足,或者硬盘出现了问题;于是我将mysql 重新安装了一次,整个问题就解决…

数据结构(四)————二叉树和堆(中)

制作不易,三连支持一下呗!!! 文章目录 前言一、堆的概念及结构二、堆的实现三.堆的应用 总结 前言 CSDN 这篇博客介绍了二叉树中的基本概念和存储结构,接下来我们将运用这些结构来实现二叉树 一、堆的概念及结构 1…

一篇文章,系统性聊聊Java注解

你好! 这类系统性聊聊***知识点的文章,是希望给大家带来对某个技术的全貌认识,如果大家喜欢,后续可以陆续更新此系列 下面,开始今天的分享 在之前,我们已经分享过注解相关的三个面试题, 今天的…

信号量、PV操作及软考高级试题解析

信号量 在并发系统中,信号量是用于控制公共资源访问权限的变量。信号量用于解决临界区问题,使得多任务环境下,进程能同步运行。此概念是由荷兰计算机科学家Dijkstra在1962年左右提出的。信号量仅仅跟踪还剩多少资源可用,不会跟踪…

Cloudera简介和安装部署

ChatGPT Cloudera 是一个基于 Apache Hadoop 的数据管理和分析平台。它是由 Hadoop 的几位创始人及早期贡献者于 2008 年创立的公司,并随着公司的不断发展,Cloudera 开始提供企业级的解决方案,帮助企业更好地利用 Hadoop 生态系统进行大数据…