Vue2组件自定义事件的绑定和解绑&事件总线

2023-12-28  本文已影响0人  扶得一人醉如苏沐晨

一、Vue2组件自定义事件绑定

功能:父组件绑定数据,子组件触发事件。(父绑子触发)

实现步骤(前三步在父组件实现,第四步在子组件实现):

  • 第一步:提供事件(组件)源
  • 第二步:给组件绑定事件(v-on:)
  • 第三步:编写回调函数,并和事件进行绑定
  • 第四步:等待事件的触发,只要事件触发,则执行回调函数。

1.1. 第一种方式:在组件标签上绑定事件

// 父组件
<template>
  <div>
    // 第一步:提供事件(组件)源 // 第二步:给组件绑定事件(v-on:简写 => @)
    <User @event="eventBinding"></User>
  </div>
</template>
<script>
import User from "./components/User.vue";
export default {
  name: "App",
  methods: {
    // 第三步:编写回调函数,并和事件进行绑定
    eventBinding(name, age) {
      console.log(name, age);
    },
  },
  components: { User },
};
</script>
// 子组件
<template>
  <div>
    <button @click="triggerEvent">触发事件</button>
  </div>
</template>
<script>
export default {
  name: "User",
  data() {
    return {
      name: "张三",
      age: 20,
    };
  },
  methods: {
    // 第四步:等待事件的触发,只要事件触发,则执行回调函数。
    triggerEvent() {
      this.$emit("event", this.name, this.age);
    },
  },
};
</script>

1.2. 第二种方式(常用):使用refs给组件绑定事件

// 父组件
<template>
  <div>
    <User ref="user"></User>
  </div>
</template>

<script>
import User from "./components/User.vue";
export default {
  name: "App",
  mounted() {
    this.$refs.user.$on("event", this.eventBinding);
  },
  methods: {
    eventBinding(name, age) {
      console.log(name, age);
    },
  },
  components: { User },
};
</script>

子组件和方式一一致

第一种 和 第二种有什么区别?

方式二可以更加灵活绑定,随时都可以绑定,方式一在视图加载完成就绑定好了

1.3. 根据方式二拓展---事件总线

1.3.1. 初始化事件总线

new Vue({
  router,
  store,
  beforeCreate() {
    /* 构造函数中的this指向实例--this就是vm */
    /* $bus就是vm实例 */
    Vue.prototype.$bus = this;
  },
  render: (h) => h(App),
}).$mount("#app");

1.3.1. 事件总线绑定

this.$bus.$on("event", this.eventBinding)

1.3.2. 事件总线解绑

this.$bus.$off("event",this.eventBinding )

1.3.1. 事件总线触发

this.$bus.$emit("event", this.name)

1.4. 第二种方式的的函数形式(不常用)

1.4.1. 普通函数

// 父组件
<template>
  <div>
    <User ref="user"></User>
  </div>
</template>

<script>
import User from "./components/User.vue";
export default {
  name: "App",
  mounted() {
    /**
     * function函数是被this.$refs.user调用的,
     * 而this.$refs.user调用的是User标签,
     * User标签是User组件的,
     * 所以这里的this调的是User实例
     *  */
    this.$refs.user.$on("event", function () {
      // 这里的this是子组件的实例,也就是User组件实例
      console.log(this);
    });
  },
  methods: {
    eventBinding(name, age) {
      console.log(name, age);
    },
  },
  components: { User },
};
</script>

1.4.2. 箭头函数

// 父组件
<template>
  <div>
    <User ref="user"></User>
  </div>
</template>

<script>
import User from "./components/User.vue";
export default {
  name: "App",
  mounted() {
    /**
     * 箭头函数没有this,
     * 所以只能往上找mounted,
     * 而mounted是App父组件的,
     * 所以this调的是App组件实例
     *  */
    this.$refs.user.$on("event", () => {
      // 这里的this是父组件的实例,也就是App组件实例
      console.log(this);
    });
  },
  methods: {
    eventBinding(name, age) {
      console.log(name, age);
    },
  },
  components: { User },
};
</script>

1.4.3. 普通函数this指向子组件实例,,箭头函数的this才是当前组件的实例

1.5. 事件只绑定一次

 <User @event.once="eventBinding"></User>
mounted() {
  this.$refs.user.$once("event", this.eventBinding);
},

二、Vue2自定义事件解绑 this.$off()

<template>
  <div>
    <button @click="triggerEvent">触发事件</button>
    <button @click="unbinding">解绑事件</button>
  </div>
</template>

<script>
export default {
  name: "User",
  data() {
    return {
      name: "张三",
      age: 20,
    };
  },
  methods: {
    triggerEvent() {
      this.$emit("event", this.name, this.age);
    },
    // 解绑事件
    unbinding() {
      // 解绑指定的事件
      this.$off("event");

      // 解绑多个事件,数组形式
      this.$off(["event", "", ""]);

      // 解绑全部事件
      this.$off();
    },
  },
};
</script>

三、事件对象多参数接收小技巧---利用es6的结构

triggerEvent() {
   this.$emit("event", this.name, 1, 2, 3, 4, 5);
},
eventBinding(name, ...params) {
   console.log(name); // 张三
   console.log(params); // [1,2,3,4,5]
},

四、当组件实例销毁后,组件上面的自定义事件全部解绑,但是原生事件并不会解绑

上一篇下一篇

猜你喜欢

热点阅读