3.13、组件自定义事件
click、keydown、keyup,这些事件都是内置事件。
Vue也支持给组件添加自定义事件。
包括两种方式:
第一种方式:直接在组件标签上绑定事件
第二种方式:通过代码来给组件绑定事件
3.13.1 直接在组件标签上绑定事件
1.关于内置事件的实现步骤。
第一步:提供事件源(以下这个按钮就是一个事件源)
第二步:给事件源绑定事件 v-on:事件名 或者 @事件名
第三步:编写回调函数,将回调函数和事件进行绑定
第四步:等待事件的触发,只要事件触发,则执行回调函数。
2.关于组件的自定义事件,实现步骤:
第一步:提供事件源(这个事件源是一个组件)
第二步:给组件绑定事件 v-on:事件名 或者 @事件名
第三步:编写回调函数,将回调函数和事件进行绑定
第四步:等待事件的触发,只要事件触发,则执行回调函数。
对于组件自定义事件来说,要想让事件发生,需要去执行一段代码。这段代码负责去触发这个事件,让这个事件发生。
这段代码在哪里写?
事件绑定在A组件上,则触发这个事件的代码要在A组件当中编写。
//·····
<div id="app" class="bg">
<h1>App组件</h1>
<girl @resiveMsg="resiveMsg" />
<son />
</div>
// ·····
methods: {
resiveMsg(msg) {
console.log('接受子组件传递的数据:', msg);
}
}
//····
<div class="bg">
<h2>girl组件</h2>
<button @click="sendMsg">传递数据</button>
</div>
//·····
methods: {
sendMsg() {
this.$emit('resiveMsg', 666)
}
}
3.父子组件之间如何通信
总结:到目前为止,父子组件之间如何通信
父---子: props
子---父:
第一种方式:在父中定义一个方法,将方法传递给子,然后在子中调用父传过来的方法,这样给父传数据。(这种方式以后很少使用)
第二种方式:使用组件的自定义事件的方式,也可以完成子向父传数据。
App组件是父组件、User组件是子组件
子组件向父组件传数据(User给App组件传数据):
在父组件当中绑定事件。
在子组件当中触发事件。
父绑定,子触发。(这句话记住)
4. 事件修饰符
对于事件的once修饰符来说,组件的自定义事件也是可以使用的。
app.vue 父组件:绑定自定义事件
<template>
<div class="app">
<h1>app父组件</h1>
<!-- 绑定自定义事件 -->
<!-- 在父组件里给子组件上绑定自定义事件,到子组件内去触发自定义事件 -->
<!-- <helloworld @event2="fun2" /> -->
<!-- 自定义事件也可以使用事件修饰符 -->
<helloworld @event2.once="fun2" />
</div>
</template>
<script>
·····
export default {
name: 'app',
methods: {
//自定义事件的函数,可以接收子组件传递过来的数据,如果是多个数据,可以用扩展运算符接收
fun2(msg,...params) {
console.log('自定义事件触发了····,', msg,params);
}
},
····
}
helloworld子组件:触发自定义事件
<template>
<div class="hello">
<h1>子组件helloworld</h1>
<button @click="dosome">点击触发自定义事件</button>
</div>
</template>
<script>
export default {
// 需求:将子组件helloworld的msg数据传递给父组件app
name: 'hellowrod',
data () {
return {
msg:'我是helloworld组件,我有个重要情报!!!'
}
},
methods:{
dosome(){
// 触发自定义的事件,并可以传递参数,传递多个
this.$emit('event2',this.msg,666,8888)
}
}
}
</script>
3.13.2 通过代码给组件绑定事件
<template>
<div class="app">
<h1>app父组件</h1>
·····
<!-- 第二种方式、通过代码绑定自定义事件 -->
<helloworld ref="hello" />
</div>
</template>
<script>
····
export default {
name: 'app',
//在组件挂载完毕后,去绑定自定义事件
mounted() {
// 这种方式更加灵活。例如:希望AJAX请求响应回来数据之后再给组件绑定事件。
this.$refs.hello.$on('event2', this.fun2)
// 保证这个自定义事件只被触发一次
//this.$refs.hello.$once('event2', this.fun2)
},
methods: {
····
fun2(msg, ...params) {
console.log('自定义事件触发了····,', msg, params);
}
},
····
}
</script>
触发还是一样在子组件中触发
这种方式有个小坑,需要注意的
this.$refs.hello.$on('自定义事件名', 函数),函数不同的写法,this指向不一样
mounted() {
// 此处有点个小坑,this的指向问题
// this.$refs.hello.$on('event2', this.fun2) //此时的this是app组件
// this.$refs.hello.$on('自定义事件名', 函数),此处的函数如果直接在里面写
// this.$refs.hello.$on('event2', function () {
// // 此时的this是hellowrod组件
// console.log(this);
// })
this.$refs.hello.$on('event2', () => {
// 此时的this是app组件
console.log(this);
})
},
3.13.3 解绑事件
哪个组件绑定的就找哪个组件解绑:
methods: {
unbinding() {
// this.$off('event2')//解绑1个事件
//this.$off(['event2', 'event1'])//解绑多个事件
this.$off()//解绑所有事件
}
}
注意:vm和vc销毁的时候,所有组件以及子组件当中的事件会全部解绑。