当前位置: 首页 > news >正文

【Vue】父子组件间如何通过事件进行通信(1)

我们来学习一下组件之间如何通过事件进行一些通信。
示例代码:

代码解读:
首先我定义了一个全局的counter组件,‍‍
然后在最外层的根组件上面去使用counter组件,它是一个计数器组件,
在这里‍‍我们可以定义一个data【第14行】,然后return一个对象叫count,值是1,‍‍
然后我把 count 传递给子组件,怎么传?‍‍

我们用冒号 count 等于 count,我向子组件传递一个叫做count的参数,它的值是data里面的 count值,‍‍也就是 1,

那么在子组件里面我们就可以去接收 count ,props 我们接收一下count,‍‍

接受完了之后,我就可以在模板里面去使用插值表达式的语法{{count}}来用 count了。‍‍
接着我想做的事情是什么?我想绑定一个事件,即@click="addOne"
有 addOne 这样的一个方法。‍‍

在methods里面我们去定义一下这个方法:

我现在的count是从哪里得到的?‍‍是不是父组件传递过来的?
数据每次点击我希望能够增加一,那么这个时候我希望让count加一,‍‍
你会想到‍‍this.count += 1;

运行效果:

大家会发现它会告诉你,你尝试在修改‍‍ prop 里面传递过来的count,它是一个只读的参数,你不能去修改它。这是Vue里面单向数据流的概念。‍‍

但是现在假设这个场景下,我就需要让count加一该怎么加?
这时候子组件不能去修改count,‍‍我就得告诉父组件,你来帮我修改一下count。

子组件怎么告诉父组件,‍‍你可以帮我修改一下count呢?
它可以这样去做,在子组件里面我们调用this.$emit这样的方法,‍‍我们向外触发一个叫做addOne这样的事件。

这句话的意思是‍‍它是一个固定的写法,也就是在组件里面,我要向外部去触发一个叫做add One这样的事件。‍‍

如果我们看counter组件向外部触发这样的一个事件,其实在父组件里面,‍‍它就可以监听这个事件,它怎么监听?

是不是@符号是监听事件的一个符号,在这里它可以去监听@addOne这样的事件,让它等于一个方法,比如说handleAddOne这样的一个方法。‍‍

你在组件内部向外触发事件的时候,这个事件的名字要是一个驼峰式的命名,‍‍但是如果你监听一个组件 它的事件的时候,在一个标签上面不能写驼峰式的这种监听的名字,‍‍你需要把@addOne变成@add-one这样的写法才可以。‍‍

这块你一定要注意,不要写错了。

一般来说触发事件的时候 我们用驼峰‍‍,
而监听事件的时候,我们用横线间隔这样的语法,

当监听到了 @add-one事件之后,‍‍我就可以在父组件里面去写一个methods 做一些处理。‍‍

这里面我写一个handleAddOne,我在这里面要做哪些事情?‍‍

this.count += 1;

这样 count 可以实现一个自增的效果。‍‍

一般来说,子组件点击的时候,‍‍执行的方法名字不建议大家写成addOne,这样的话实际上不太规范,‍‍应该写成handleClick 来处理点击,

当然你要处理谁的点击?你处理这个item,‍‍代码如下:

然后向外触发一个addOne这样的事件,我们这块写成handleAddOne,‍‍
因为你触发的事件名字叫做addOne,如果你事件名字是click的话,我就叫做handlerclick。‍‍

处理 addOne事件,执行handleAddOne方法,然后执行this.count += 1;

写了这么多,我们回过头来看整个逻辑是什么样的。‍‍
首先我子组件接收你父组件传递过来的count,‍‍你传过来的是几,我就展示的是几,

一开始你传递过来的这个值肯定是 1 ,所以我展示就是 1,
接着当我点击的时候,我触发了一个自身的事件 叫做addOne
那父组件接收到了这个事件,它执行handleAddOne这个方法,把count加 1,

所以count变成了 2,‍‍你的count变化会自动的传给子组件,‍‍子组件接收 count,这个时候子组件的 count 也变成2了,所以你这块展示的内容就变成了2。

通过这个例子我们能看到在Vue里面我可以给一些标签,比如说div标签绑定一些事件,‍‍这个事件和我们原生的事件理解起来很相似,当然我们还可以给组件去绑定事件,其实也是给这样的一个标签,‍‍只不过这个标签变成一个组件,

那这个组件接收的事件,不一定非得是click事件,‍‍还可以是一些自定义的事件。‍‍

我们可以通过这样的自定义事件实现父子组件的一些通信,‍‍尤其是子组件向父组件传递一些信息的时候,‍‍我们就可以这么去做。

现在我并没有传递特别多的信息,只是我在点击的时候‍‍告诉父组件,一个事件叫做addOne的事件被触发了,父组件接收到这个事件,它会把 count加 1,‍‍但实际上你可以携带更多的数据,怎么携带?

比如说我这块可以触发一个事件叫做add,‍‍后面我可以传递一个参数 2,

意思是‍‍我子组件每次点击的时候,父组件你的count要帮我加2,这个时候我们可以怎么去改上面的代码?

首先这块我监听的事件里面触发的是add,外面我父组件监听的事件也应该是add,‍‍
就是handleAdd这个方法里面,方法里面做一些处理,这个方法里实际上是能接收到你传递过来的这些参数的,怎么接收的?‍‍

比如说 param 你传递一个 2,‍‍它就会放到 param 里面去,因为你看触发了一个add事件,这里监听事件你额外带了参数,‍‍监听这个事件的方法,就能拿到这个参数,每次我们加这个参数就可以了。‍‍

实际上在父子组通信的时候,‍‍子组件可以向父组件通过事件这种机制传递更多的参数内容,比如说你还可以再传一个3,‍‍代码如下:

接下来再对代码做一些改造
我们可以看到现在‍‍子组件触发事件之后,父组件接收到事件之后,执行handleAdd这个方法把count的值算出来,实际上计算这一步‍‍我可以在子组件里去完成。怎么完成?

当我子组件被点击的时候,触发 add 事件的时候,‍‍可以直接把新的count值在这里算出来,比如说你让count加3。代码改造如下:

这里我就让count加3,父组件监听这个事件之后,‍‍这块直接就获取到最新的count的值,直接让this点count等于count值就可以了。‍‍

如果一个子组件向外部触发一些事件的话,我们其实可以在这里‍‍去写一个emits这样的对象或者数组。‍‍
再来看代码示例:

比如说我写一个emits,这里面我写了一个add,‍‍它指的是什么?它指的是我这个组件会向外部去触发add这样的事件,当你这么去写之后,你到页面上去刷新,‍‍其实不会有什么变化一样的。‍‍

但是假设你在emits里面写了一个minus,比如说减法,‍‍代码如下:

你点击的时候你会发现什么?

什么意思?你向外触发的是add这样的事件,‍‍但是实际上 emits 组件定义的时候我只会向外触发 minus这样的事件,所以它俩匹配不上,Vue就会给你做一个警告,‍‍

所以 emits 这样的一个对象里的属性,‍‍它的意义在于说让你看到这个 emits 就直接知道这个组件到底会向外触发什么样的事件。‍‍

比如说你后面可能会有很多的这样的方法,里里面会触发不同的这种事件,比如说a,

我自己逐行地去看代码,去梳理到底向外触发了多少个事件都比较麻烦,‍‍如果在 emits 里面,你把这些东西都写在这里,后面的维护性可能会更高一些,它是这样的一个作用。

当然它不局限于你在这里写一个数组,你还可以写一个对象,如果写一个对象就更有意思了,‍‍我们可以在这里写一个add,它指的是我会向外触发add这样的一个事件,

当然这个事件后面其实你还可以写一个函数,它会接收到你向外传递的参数的值,‍‍比如说你触发 add 事件的时候,向外传递的参数是不是只有一个,它是一个count 嘛,我可以‍‍在这里做一个判断,if count 大于零,return true,否则我就return false。‍‍
此时代码示例:

什么意思?也就是说当你向外触发事件的时候,我会检验事件传递过去的参数,如果这个参数大于0,‍‍我就同意你往外传,如果小于0我就不允许你往外传,同时会给你警告。‍‍

但是假设我把改成小于0,此时代码示例:

点击它就会报警告,

说什么?说你 add的触发的事件携带的 event arguments 事件参数是校验没有通过的。

所以大家记得你还可以通过 emits 对事件向外触发的参数做一些校验。

相关文章:

  • Vue----生命周期函数
  • 瑞吉外卖 —— 10、Redis
  • 信息安全技术实验:网络嗅探与欺骗
  • 【SQL刷题】DAY15----SQL联结表专项练习
  • Python基础学习
  • 2021了,真的不要再说 Node.js 是一门编程语言了
  • shell 编程之变量总结
  • [Mybatis-Plus笔记] MybatisPlus-03-QueryWrapper条件构造器
  • STM32F1定时器-PWM输出
  • CNN天气识别
  • 基于SpringBoot+Vue的校园招聘管理系统(Java毕业设计)
  • java File类基本概念基本构造方法使用
  • 基于Java微服务方案的商品秒杀系统
  • 谷粒商城 高级篇(一) --------- ElasticSearch 的简介与安装
  • mybatis的sql标签
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • Intervention/image 图片处理扩展包的安装和使用
  • jquery cookie
  • nginx 配置多 域名 + 多 https
  • 高性能JavaScript阅读简记(三)
  • 给Prometheus造假数据的方法
  • 关于Java中分层中遇到的一些问题
  • 缓存与缓冲
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 如何邀请好友注册您的网站(模拟百度网盘)
  • 使用 5W1H 写出高可读的 Git Commit Message
  • 推荐一款sublime text 3 支持JSX和es201x 代码格式化的插件
  • 正则与JS中的正则
  • [Shell 脚本] 备份网站文件至OSS服务(纯shell脚本无sdk) ...
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • Spring Batch JSON 支持
  • ​​​​​​​Installing ROS on the Raspberry Pi
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • (二)Linux——Linux常用指令
  • (二)斐波那契Fabonacci函数
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (四)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • .net操作Excel出错解决
  • .NET的微型Web框架 Nancy
  • .net专家(张羿专栏)
  • /bin、/sbin、/usr/bin、/usr/sbin
  • /usr/lib/mysql/plugin权限_给数据库增加密码策略遇到的权限问题
  • /var/spool/postfix/maildrop 下有大量文件
  • @Not - Empty-Null-Blank
  • [ 环境搭建篇 ] 安装 java 环境并配置环境变量(附 JDK1.8 安装包)
  • [100天算法】-目标和(day 79)
  • [2019.2.28]BZOJ4033 [HAOI2015]树上染色