自定义事件
子向父传递数据的实现,可以通过自定义事件实现
1. 认识自定义事件
Vue中已经提供了很多内置事件:click,enter,keyDown等,Vue同时也支持自定义事件
2. 实现自定义事件
实现方式有两种:
- 通过在父组件中使用到子组件的地方,使用@或者v-on加上事件名="xxxx", xxxx事件函数
- 通过在父组件中使用到子组件的地方,使用ref
vue
<template>
<div>
<Header></Header>
<!-- changeTotalNum当做变量的写法传递给子组件 -->
<List :changeTotalNum='changeTotalNum' ref="listRef"></List>
<Footer v-on:updateAllDone="updateAllDone" ref="footerRef"></Footer>
</div>
</template>
<script>
import Header from "@/components/Header.vue";
import List from "@/components/List.vue";
import Footer from "@/components/Footer.vue";
export default {
name: 'App',
components: {
Header, List, Footer
},
methods: {
changeTotalNum(totalNum) {
this.totalNum = totalNum
},
updateAllDone(done) {
this.$refs.listRef.updateAllDone(done)
},
},
mounted() {
//this.$refs.footerRef.$on('updateAllDone', this.updateAllDone)
}
}
</script>
3. 解绑事件
unbind() { // vue生命周期在beforeDestroy会处理自定义事件
// this.$off('addTodo') // 解绑一个事件
// this.$off(['addTodo', 'xxx']) // 解绑多个事件
this.$off() // 解绑所有事件
}
但是原生事件不受影响,vc或者vm调用$destory方法后,自定义事件会解绑$destory在后面使用不用亲自调用,路由切换的时候会自动调用$destory
4. 注意事项
js
// 使用ref属性进行事件绑定的时候,如果不使用下面的写法
this.$refs.footerRef.$on('updateAllDone', this.updateAllDone)
// 而是使用内联函数传入参数
this.$refs.footerRef.$on('updateAllDone', function(){
console.log(this) // 这个this不是当前组件的vc,而是事件发发生的组件vc
}))
但是为何使用this.updateAllDone
函数内部如果使用this就是当前组件的vc呢,因为this.updateAllDone
写在了methods里面
- 它是一种组件间通信的方式,适用于:组件===>父组件
- 使用场景: A是父组件,B是子组件,B想给A传输数据,那么就要在A中给B绑定自定义事件
- 绑定自定义事件:
- 第一种方式,在父组件中:
<Demo @jack="test" />
或<Demo v-on:jack="test"/>
- 第二种方式,在父组件中:
js
<Demo ref="demo">
....
mounted(){
this.$refs.xxx.$on('jack', this.test)
}
- 若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法。 触发自定义事件:
this.$emit('jack', 数据)
- 解绑自定义事件:
this.$off('jack')
- 组件上也可以绑定原生DOM事件,需要使用native修饰符。否则就不能识别,比如click事件也会被认为是自定义事件,也就是说组件上面都是自定义事件
- 注意: 通过
this.$refs.xxx.$on('jack', 回调)
绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出现问题! 可以使用vue的开发者工具dev-tools查看自定义事件: