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数据传递给父组件appname: '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销毁的时候,所有组件以及子组件当中的事件会全部解绑。