我们来学习一下组件之间如何通过事件进行一些通信。示例代码:
代码解读:首先我定义了一个全局的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这样的事件。
这句话的意思是它是一个固定的写法,也就是在组件里面,我要向外部去触发一个叫做addOne这样的事件。
如果我们看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】父子组件间如何通过事件进行通信(1)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/104575.html