通过vue手动封装on、emit、off的代码详解

下面就是“通过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技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • Vue状态机的开启与停止操作详细讲解

    Vue状态机的开启与停止操作详细讲解 Vue状态机是实现应用程序状态管理的一种常见方式。它是一个基于Vue框架的库,可以帮助你在Vue应用程序中轻松管理状态的变化。在Vue中,状态机通常是一个基于RxJS或其他数据流程库的事件流,它们被用于自动更新视图和状态。 开始状态机 要开始状态机,您需要在Vue应用程序中引入状态机库。通常,您可以通过npm包管理器安装…

    Vue 2023年5月27日
    00
  • Vue自定义指令详细

    Vue自定义指令详细攻略 Vue提供了许多内置指令用于操作DOM元素,如v-if、v-show、v-bind等。但是,如果我们想要自定义一些不同于Vue提供的指令来操作DOM元素,该怎么做呢?这时候,Vue的自定义指令就派上用场了。 自定义指令的基本使用 Vue允许开发者自定义指令,只需要在Vue实例中的directives选项中注册即可。 自定义指令需要定…

    Vue 2023年5月27日
    00
  • vue实现文字滚动效果

    一、安装vue-infinite-scroll插件 vue-infinite-scroll是一个插件库,旨在为Vue提供无限滚动功能。可以使用CDN,在head标签中添加以下内容: <script src="https://cdn.jsdelivr.net/npm/vue-infinite-scroll@2.0.2/dist/vue-infi…

    Vue 2023年5月29日
    00
  • vue如何添加数组页面及时显示

    当我们在 Vue 中使用数组时,我们可能需要通过添加或删除元素来更新页面。Vue 提供了一些内置的方法,来处理这些问题。下面就是一些步骤,可以让你在 Vue 中应用这些方法,以及让你了解 Vue 如何添加数组页面及时显示。 步骤一:定义数组 第一步是定义一个数组,你可以在 data 函数中定义数组,也可以将其定义为组件实例的属性。例如,下面是将数组定义为组件…

    Vue 2023年5月28日
    00
  • 详解Vue中的基本语法和常用指令

    详解Vue中的基本语法和常用指令 Vue的基本语法 Vue.js是一个用于构建交互式Web界面的渐进式JavaScript框架。其中,最基本的语法就是Vue实例。创建Vue实例时,需要提供一个JavaScript对象作为参数,这个对象称之为“选项对象”。 选项对象有很多属性,其中最重要的是data属性。data属性中定义了Vue实例中用到的数据。例如下面这个…

    Vue 2023年5月27日
    00
  • 十个有用的自定义Vue钩子函数总结

    下面详细讲解一下”十个有用的自定义Vue钩子函数总结”的攻略: 1. 什么是Vue钩子函数 Vue.js提供了很多生命周期钩子函数,我们可以在不同的阶段对应的函数中执行代码。其实,除了Vue.js官方提供的钩子函数,我们还可以自己定义钩子函数,方便我们在需要的时候进行统一处理。 2. 自定义Vue钩子函数的常用场景 2.1 全局数据加载提示 在请求全局数据时…

    Vue 2023年5月27日
    00
  • vue组件间通信六种方式(总结篇)

    那么我来介绍一下“Vue组件间通信六种方式(总结篇)”的具体内容和完整攻略。 一、背景 在Vue的组件化开发中,组件之间的通信是很常见的需求。Vue提供了很多种方式来实现组件间的通信,但每种方式都有其自身的优缺点,需要根据具体场景来选择最合适的方案。 二、六种通信方式 下面是六种组件通信方式,具体实现可以查阅对应的示例代码。 1. props + emit …

    Vue 2023年5月27日
    00
  • Springboot实现Shiro整合JWT的示例代码

    下面来详细讲解如何实现Spring Boot整合Shiro和JWT的示例代码。 简介 Shiro是一个强大的安全框架,提供了多种安全特性,例如:认证、授权、加密等等。JWT是一种轻量级的认证机制,它可以使用JSON格式存储用户信息,并且可以在客户端和服务端之间传递。 本文将介绍如何通过Spring Boot实现Shiro整合JWT的示例代码。 示例1:环境搭…

    Vue 2023年5月28日
    00
合作推广
合作推广
分享本页
返回顶部