下面就是“通过Vue手动封装on、emit、off的代码详解”的攻略。
什么是on、emit、off
on、emit、off是Vue中的三个方法。其中,on用于监听自定义事件的回调函数,emit用于触发子组件中自定义事件,off用于移除事件监听器。
封装on、emit、off
在Vue框架中,我们不需要手动封装on、emit、off,可以直接在组件中使用这三个方法。不过,如果你想要手动封装这三个方法,可以按照以下步骤进行。
封装on方法
我们可以在Vue原型上添加一个$on方法,用于监听自定义事件的回调函数。
Vue.prototype.$on = function(event, fn){
const vm = this;
if(Array.isArray(event)){
for(let i = 0, l = event.length; i < l; i++){
this.$on(event[i], fn);
}
}else{
(vm._events[event] || (vm._events[event] = [])).push(fn);
}
return vm;
};
上述代码中,我们判断如果event是一个数组,则遍历数组中每一个事件名称,执行$on方法,将所有事件全部监听;如果event是一个字符串,则将监听函数推入对应事件的回调函数数组里。
封装emit方法
我们可以在Vue原型上添加一个$emit方法,用于触发子组件中的自定义事件。
Vue.prototype.$emit = function(event){
const vm = this;
let cbs = vm._events[event];
if(cbs){
const args = Array.prototype.slice.call(arguments, 1);
for(let i = 0, l = cbs.length; i < l; i++){
try{
cbs[i].apply(vm, args);
}catch(e){
console.error(e);
}
}
}
return vm;
};
上述代码中,我们通过判断当前组件是否存在对应的回调函数数组,然后执行回调函数,并传入参数。
封装off方法
我们可以在Vue原型上添加一个$off方法,用于移除事件的监听器。
Vue.prototype.$off = function(event, fn){
const vm = this;
if(!arguments.length){
vm._events = Object.create(null);
return vm;
}
if(Array.isArray(event)){
for(let i = 0, l = event.length; i < l; i++){
this.$off(event[i], fn);
}
return vm;
}
const cbs = vm._events[event];
if(!cbs){
return vm;
}
if(!fn){
vm._events[event] = null;
return vm;
}
let cb;
let i = cbs.length;
while(i--){
cb = cbs[i];
if(cb === fn || cb.fn === fn){
cbs.splice(i, 1);
break;
}
}
return vm;
};
上述代码中,我们加入了移除所有事件监听器、移除多个事件监听器和移除单个事件监听器三种情况,可以进行跟细粒度的操作。
示例说明
假如我们有一个子组件中有一个按钮,点击此按钮时触发自定义事件,实现父组件监听该事件打印日志。
子组件:
<template>
<div>
<button @click="handleClick">触发事件</button>
</div>
</template>
<script>
export default {
name: 'ChildComponent',
methods: {
handleClick(){
this.$emit('my-event');
}
}
}
</script>
父组件:
<template>
<div>
<child-component @my-event="handleLog"></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
name: 'ParentComponent',
components: {
ChildComponent
},
methods: {
handleLog(){
console.log('自定义事件my-event被触发');
}
}
}
</script>
当我们点击子组件中的按钮时,console中会输出“自定义事件my-event被触发”的日志。
再看一个示例,此次我们需要给子组件中的多个事件添加监听器,并移除相应的监听器。
子组件:
<template>
<div>
<button @click="handleClick">触发事件1</button>
<button @click="handleClick">触发事件2</button>
</div>
</template>
<script>
export default {
name: 'ChildComponent',
methods: {
handleClick(){
this.$emit('my-event1');
this.$emit('my-event2');
}
}
}
</script>
父组件:
<template>
<div>
<child-component></child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
name: 'ParentComponent',
components: {
ChildComponent
},
created(){
this.$on(['my-event1', 'my-event2'], this.handleLog);
},
methods: {
handleLog(){
console.log('自定义事件my-event1、my-event2被触发');
this.$off(['my-event1', 'my-event2'], this.handleLog);
}
}
}
</script>
在父组件中created钩子中,我们监听了两个事件my-event1和my-event2,并分别在handleLog方法中处理二者并移除监听器。当我们在子组件中点击两个按钮时,console中会输出“自定义事件my-event1、my-event2被触发”的日志,且日志只会输出一次。
通过这两个例子,相信您已经明白了如何手动封装on、emit、off方法了。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:通过vue手动封装on、emit、off的代码详解 - Python技术站