一、组件概述
1.组件的自定义事件是什么?
一种组件间的通信方式,适用于子组件传递数据给父组件(子传父)
2.使用在哪个场景里面?
- A是父组件,B是子组件,B想给A传递数据,
- 那么就要在A中给B绑定自定义事件,当这个自定义事件被触发后会向A传递数据,紧接着调用A中的一个函数进行接收数据(也就是事件的回调在A之中)
3.怎么绑定和触发自定义事件?
假如子组件是Demo,父组件是app,子组件已经在父组件中被引用了,例如要给demo绑定一个hello自定义事件,在A中事件的回调是update
1.第一种方式:
- 父组件中绑定:<Demo @绑定事件名 = "回调事件名" />
- 子组件中使用:this.$emit('绑定事件名',参数)
在父组件中<Demo v-on:hello = "update" />或者<Demo @hello = "update" />
- 这种做法就相当于在子组件Demo组件实例对象身上添加了一个hello函数事件,只要hello事件被触发,update函数就会被调用
- 只要给谁绑定自定义事件,就去哪个组件中触发自定义事件
然后在父组件中定义一个update的事件回调函数接收子组件传递过来的参数
在子组件:this.$emit('hello',传递的参数)触发自定义事件,并向父组件传递数据
调用子组件的实例对象vc身上的$emit事件来触发子组件身上被绑定的自定义事件
2.第二种方式:
- 获取子组件实例对象<Demo ref="xxx" />
- 在父组件中给子组件绑定事件:this.$refs.xxx.$on('绑定事件名',事件回调)
- 子组件中使用:this.$emit('绑定事件名',参数)
在父组件中<Demo ref="demo" />
- 通过之前的ref属性学习,我们知道,ref在组件上使用会得到这个组件的实例对象,所以我们会在app父组件中得到Demo子组件的vc(组件实例对象)
在父组件中写一个钩子函数mounted(),给子组件Demo组件的实例对象绑定事件,待hello事件被触发后,调用update函数接收数据
mounted(){
this.$refs.demo.$on('hello',update)
}
注意:
通过this.$refs.xxx.$on('绑定事件名',事件回调)绑定自定义事件时,事件回调要么配置在methods中,要么写成箭头函数(如果写成普通函数会造成this指向错乱)
4.如何解绑自定义事件?
this.$off('绑定的事件名’)
- 在父组件使用组件实例对象身上的$off进行解绑
-
若解绑多个事件,则使用数组包裹,如果不传参数,所有的自定义事件都解绑
5.怎么在组件上绑定原生DOM事件?
<Demo @click.native = "show" />
加上native之后就将click事件给demo组件的DOM结构上了,只要点击demo组件,就会触发show函数
6.如何让自定义事件只触发一次?
若想让自定义事件只能触发一次,可以使用once修饰符,或者$.once方法
二、举例
例如父组件是app,子组件是student,student组件向app组件传递name数据给studentName并显示到页面上
1.第一种方法:
1.在app组件中的student标签中给student绑定自定义事件(这里名叫hello事件),事件的回调叫getStudent
2.然后在app组件中配置methods写入getStudent回调函数,将接收到的数据赋给studentName
3.在子组件中写入一个button标签,随意绑定一个事件,在methods中写入,在函数逻辑中通过$emit触发给student绑定的自定义事件,并将name传递过去,紧接着就会调用第二步在app组件中写入的getStudent回调函数,将接收到的数据赋给studentName
效果图:点击传递信息按钮后出现
2.第二种方法:
1.在app父组件种的子组件标签上使用ref属性,获取student的实例对象,
2.然后在生命周期钩子中绑定自定义事件
3.同第一种方法第三步
效果图:点击传递信息按钮后出现
三、v-on与ref绑定事件的区别
利用ref绑定事件较利用v-on绑定事件具有更大的灵活性,因为this.$refs写在了生命周期钩子函数中,可以在特定的时间干特定的事情,例如可以让事件晚几秒钟被触发