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.mzph.cn/web/11436.shtml

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

相关文章

Java面试八股之Java中的IO流分为几种

Java中的IO流分为几种 按数据单位分类: 字节流(Byte Stream):以字节(8位二进制数)为基本单位进行数据读写。字节流适合处理所有类型的数据,包括文本、图像、音频、视频等二进制文件。抽象基类…

打破地域界限,HubSpot海外获客系统引领企业走向国际化

在全球化的浪潮中,企业如何精准把握海外市场、高效获取并转化目标客户,已成为决定其市场地位与未来发展的关键因素。HubSpot海外获客系统以其独特的视角、强大的功能和卓越的性能,正在引领全球营销进入一个新的时代。今天运营坛将深入剖析Hub…

阿里巴巴找黄金宝箱(II) - 贪心思维

系列文章目录 文章目录 系列文章目录前言一、题目描述二、输出描述三、输入描述四、java代码五、测试用例 前言 本人最近再练习算法,所以会发布自己的解题思路,希望大家多指教 一、题目描述 一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发…

工作组PTH

文章目录 简述RID 500本地管理员密码喷洒何为RIP 500 安全标识符SID与RIDPTH为何必须是RID 500CrackMapExec进行密码喷洒 简述 在工作组PTH中为什么只有administrator账号可以,下面进行讲解与利用。RID 500本地管理员密码喷洒 何为RIP 500 安全标识符 安全标识符 安全标识符…

触摸OpenNJet,云原生世界触手可及

🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​💫个人格言:“没有罗马,那就自己创造罗马~” 文章目录 导言OpenNJet云原生引擎介绍云原生平台的介绍优化与创新 为什么选择OpenNJet云原生引擎如何在windo…

Pytorch基础:torch.cuda.set_device函数

相关阅读 Pytorch基础https://blog.csdn.net/weixin_45791458/category_12457644.html?spm1001.2014.3001.5482 torch.cuda.set_device函数用于设置当前使用的cuda设备,在当拥有多个可用的GPU且能被pytorch识别的cuda设备情况下(环境变量CUDA_VISIBLE_…

【AI大模型】自动生成红队攻击提示--GPTFUZZER

本篇参考论文为: Yu J, Lin X, Xing X. Gptfuzzer: Red teaming large language models with auto-generated jailbreak prompts[J]. arXiv preprint arXiv:2309.10253, 2023. https://arxiv.org/pdf/2309.10253 一 背景 虽然LLM在今天的各个领域得到了广泛的运用…

MacOS java多版本安装与管理

Home - SDKMAN! the Software Development Kit Manager # 安装sdkman curl -s "https://get.sdkman.io" | bashsource "$HOME/.sdkman/bin/sdkman-init.sh"sdk version正常出现sdkman版本号就安装成功了 # 安装java # 安装java8 sdk install java 8.0…

论文笔记:仅一个进程故障就无法达成共识

仅一个进程故障就无法达成共识 仅一个进程故障指的是在异步的分布式系统中 摘要 异步系统的共识问题(consensus)涉及一组进程,其中有的进程可能不可靠(unreliable)。共识问题要求可靠的进程一致地从两个侯选中决定&…

【MATLAB源码-第207期】基于matlab的单相光伏并网系统仿真,并网策略采用基于扰动观测法的MPPT模型和使用电压电流双闭环SPWM控制。

操作环境: MATLAB 2022a 1、算法描述 本文将重点分析光伏发电最大功率点跟踪(MPPT)技术和逆变器的并网控制技术,并在Simulink环境下建立模拟系统,以体现这些技术的应用与效果。文章结构如下:首先简介光伏…

OpenAI下周发布更新;TikTok将自动标记AIGC;智谱AI亮相2024 ICLR

OpenAI 官宣下周举办直播发布更新 OpenAI 今日凌晨官宣,将在当地时间 5 月 13 日上午十点(北京时间 5 月 14 日凌晨两点)在官网进行直播,届时将演示一些 ChatGPT 和 GPT-4 的更新。 OpenAI CEO Sam Altman 补充表示,届…

2024软件测试面试必备面试题大全

1. 请自我介绍一下(需简单清楚的表述自已的基本情况,在这过程中要展现出自信,对工作有激情,上进,好学) 面试官您好,我叫###,今年26岁,来自江西九江,就读专业是电子商务,…

PCIE协议-2-事务层规范-MEM/IO/CFG request rules

2.2.7 内存、I/O和配置请求规则 以下规则适用于所有内存、I/O和配置请求。每种类型的请求还有特定的额外规则。 所有内存、I/O和配置请求除了常见的头标字段外,还包括以下字段:requester ID[15:0]和Tag[9:0],形成事务ID。Last DW BE[3:0] a…

ICode国际青少年编程竞赛- Python-2级训练场-列表遍历

ICode国际青少年编程竞赛- Python-2级训练场-列表遍历 1、 for i in range(3):Flyer[i].step(2) Dev.step(6)2、 for i in range(7):Flyer[i].step() Dev.step(Item.x - Dev.x)3、 for i in range(3):Flyer[i].step(1) Dev.step(4) Dev.turnLeft() Dev.step(2) Dev.turnL…

【APM】在Kubernetes中搭建OpenTelemetry+Loki+Tempo+Grafana链路追踪(一)

文章目录 1、最终效果2、前提准备2、环境信息3、服务集成(Opentelemetry ->Tempo)3.1 上报链路数据3.1.1 下载opentelemetry-agent3.1.2 启动配置业务app3.1.3 配置opentelemetry输入输出3.1.4 配置grafana datasource3.1.4.1 配置tempo3.1.4.2 配置l…

快速判断出485从站设备是否支持MODBUS RTU无线通讯

对于变频器和仪表设备,都支持485串口通讯,那么怎么判断从站设备支持那种协议呢?通常分为两种方式去判断:1.从设备参数参看2.从设备通讯报文查看。本次文章以以台达MH300系列变频器为例。 1.从设备通讯参数查看 使用设备之前一定…

资料如何打印更省钱

在日常工作和学习中,我们经常需要打印各种资料。然而,随着打印成本的不断提高,如何更省钱地打印资料成为了大家关注的焦点。今天,就为大家分享一些资料打印的省钱技巧,并推荐一个省钱又省心的打印平台。 首先&#xff…

【话题】软件开发的航海图:程序员的实用神器探秘

大家好,我是全栈小5,欢迎阅读小5的系列文章,这是《话题》系列文章 目录 背景一、代码编写二、版本控制三、测试与调试四、部署与运维五、总结文章推荐 背景 在软件开发的广阔海洋中,每一位程序员都是一位勇敢的航海家&#xff0c…

数据结构-栈的讲解

栈的概念及结构 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端称为栈顶,另一端称为栈底(因为先进后出)。栈中的数据元素遵守后进先出LIFO(Last In Firs…

学习注意力机制并将其应用到网络中

什么是注意力机制 注意力机制的核心重点就是让网络关注到它更需要关注的地方。 当我们使用卷积神经网络去处理图片的时候,我们会更希望卷积神经网络去注意应该注意的地方,而不是什么都关注,我们不可能手动去调节需要注意的地方,…