自定义事件学习
1、什么是自定义事件?
自定义事件顾名思义,就是我们自己定义的事件,事件的名称以及回调等都由我们自己设计实现。
2、自定义事件是干什么用的?
自定义事件是一种组件间的通信方式,适用于子组件向父组件传值。
3、自定义事件的实现:
第一种方式:
父组件通过v-on定义自定义事件v-on可以简写为@例:v-on:demo="send"可以写为@demo="send"
父组件:
App.vue:
<template>
<div class="app">
<h1>{{msg}}</h1>
<TestA v-on:demo="send"/>
</div>
</template>
<script>
import TestA from './components/TestA'
export default {
name:'App',
components:{TestA},
data(){
return{
msg:'自定义事件'
}
},
methods:{
send(name){
console.log('send被调用了', name)
},
},
}
</script>
子组件通过$emit向父组件传值
子组件:
TestA.vue:
<template>
<div>
<button @click="sendName">点击触发自定义事件</button>
</div>
</template>
<script>
export default {
name:'TestA',
data(){
return{
name:'路飞',
age:18
}
},
methods:{
sendName(){
this.$emit('demo',this.name)
}
}
}
</script>
第二种方式:
通过ref属性拿到TestA组件组件的实例对象(vc),在组件挂载完成之后(mounted)使用this.$refs.组件名.$on('自定义事件名', 回调函数)完成对子组件自定义事件的绑定父组件中需要改变的:
App.vue:
<TestA ref="testa"/>
<script>
methods:{
send(name){
console.log('send被调用了', name)
},
mounted(){
this.$refs.testa.$on('demo',this.send)
}
</script>
子组件没有变化
一次性自定义事件:
v-on:事件名.once="XXXX"
或者
this.$refs.ref属性名.$once("事件名", 事件内容)
注意:由于是子组件向父组件传值,所以传值的动作在子组件中;父组件接收子组件的数据,所以绑定的动作在父组件中。
4、自定义事件的v-model
v-model在Vue中用于双向绑定,是一种语法糖。v-model默认会利用名为 value 的 prop 和名为 input 的事件。例:
<input v-model="parentData">
等价于
<input
:value="parentData"
@input="parentData = $event.target.value">
/*
$event 指代当前触发的事件对象;
$event.target 指代当前触发的事件对象的dom;
$event.target.value 就是当前dom的value值;
*/
但是上述的写法只适用于input,因为v-model在内部为不同的输入元素使用不同的属性并抛出不同的事件。那如果不是input而是checkbox呢?这时候我们就需要用到model选项了,model 选项可以指定当前的事件类型和传入的 props。具体的步骤是什么呢?第一步,先为组件增加model对象:
model: {
prop: 'checked',
event: 'change'
},
第二步,在组件的props中注册checked属性:
props:{
checked: Boolean
}
第三步,修改template,增加checkbox和选中的状态描述:
<input
type="checkbox"
v-bind:checked="checked"
@change="$emit('change', $event.target.checked)"
>
这三步做完后子组件代码如下:
Vue.component('base-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean
},
template: `
<input
type="checkbox"
v-bind:checked="checked"
v-on:change="$emit('change', $event.target.checked)"
>
`
})
最后,在父组件中的template中使用 base-checkbox 时就可以通过v-model来实现 base-checkbox 组件的双向绑定了。
<base-checkbox v-model="lovingVue"></base-checkbox>
这里的 lovingVue 的值就会和checked的值绑定了,同时当触发一个 change 事件并附带一个新的值的时候,这个 lovingVue将会被更新为所附带的值。
5、将原生事件绑定到组件
在自定义组件的根元素上直接监听一个原生事件时,例如:
<base-input v-on:focus="onFocus"></base-input>
onFocus事件是不会触发的,因为我们自定义的组件它并不是原生html里面的标签,所以直接绑定事件是不好用的。这时候需要在原生事件后面加上 .native修饰符,onFocus事件就会触发了。
6、.sync修饰符
sync的意思是同步。.sync修饰符可以实现子组件与父组件的双向绑定,并且可以实现子组件同步修改父组件的值。一般情况下,父组件通过 props 将值传给子组件,子组件再通过 $emit 将值传给父组件,父组件通过事件监听获取子组件传过来的值。使用.sync修饰符可以简化父子之间传值的代码, .sync修饰符实际上也是一个语法糖。例:
<text-document
v-bind:title="doc.title"
v-on:update:title="doc.title = $event" //在vue的字符串模板中直接用$event是取$emit传递的第一个参数等同,即this.$emit('update:title', newTitle)
></text-document>
等价于
<text-document v-bind:title.sync="doc.title"></text-document>
7、自定义事件解绑的实现:
自定义事件解绑需要在子组件中通过$off解绑自定义事件
子组件:
TestA.vue:
<template>
<div>
<button @click="sendName">点击触发自定义事件</button>
<button @click="noBand">解绑自定义事件</button>
</div>
</template>
<script>
methods:{
sendName(){
this.$emit('demo',this.name)
},
noBand(){
this.$off('demo');
}
}
</script>
注意:如果要解绑多个事件,this.$off(["demo1","demo2"...]);如果this.$off中不传递任何参数,那么此组件绑定的所有自定义事件都会解绑
总结:自定义事件是实际开发工作中比较常用的方法,在进行某些操作时,使用自定义事件可以节省开发时间,减少代码冗余,提高工作效率。
转载自:https://segmentfault.com/a/1190000042509059