Vue学习之--------组件自定义事件(绑定、解绑)(2022/8/21)

1、基础知识

  1. 一种组件间通信的方式,适用于:子组件 ===> 父组件

  2. 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。

  3. 绑定自定义事件:

    1. 第一种方式,在父组件中:<Demo @zyz="test"/><Demo v-on:zyz="test"/>

    2. 第二种方式,在父组件中:

      <Demo ref="demo"/>
      ......
      mounted(){
         this.$refs.xxx.$on('zyz',this.test)
      }
      
    3. 若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法。

  4. 触发自定义事件:this.$emit('zyz',数据)

  5. 解绑自定义事件this.$off('zyz')

  6. 组件上也可以绑定原生DOM事件,需要使用native修饰符。

  7. 注意:通过this.$refs.xxx.$on('zyz',回调)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!


2、代码实例

2.1 App.vue

<template>
  <div class="app">
    <h1>{{ msg }},学生姓名是:{{ studentName }}</h1>

    <!-- 通过父组件给子组件传递函数类型的props实现:子给父传递数据 -->
    <School :getSchoolName="getSchoolName" />

    <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第一种写法,使用@或v-on) -->
    <!-- <Student @atguigu="getStudentName" @demo="m1"/> -->

    <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第二种写法,使用ref) -->
    <Student ref="student" @click.native="show" />
  </div>
</template>

<script>
import Student from "./components/Student";
import School from "./components/School";

export default {
  name: "App",
  components: { School, Student },
  data() {
    return {
      msg: "你好啊!",
      studentName: "",
    };
  },
  methods: {
    getSchoolName(name) {
      console.log("App收到了学校名:", name);
    },
    getStudentName(name, ...params) {
      console.log("App收到了学生名:", name, params);
      this.studentName = name;
    },
    m1() {
      console.log("demo事件被触发了!");
    },
    show() {
      alert(123);
    },
  },
  mounted() {
    this.$refs.student.$on("atguigu", this.getStudentName); //绑定自定义事件
    // this.$refs.student.$once('atguigu',this.getStudentName) //绑定自定义事件(一次性)
  },
};
</script>

<style scoped>
.app {
  background-color: gray;
  padding: 5px;
}
</style>


2.2 school.vue

<template>
  <div class="school">
    <h2>学校名称:{{ name }}</h2>
    <h2>学校地址:{{ address }}</h2>
    <button @click="sendSchoolName">把学校名给App</button>
  </div>
</template>

<script>
export default {
  name: "School",
  props: ["getSchoolName"],
  data() {
    return {
      name: "尚硅谷",
      address: "北京",
    };
  },
  methods: {
    sendSchoolName() {
      this.getSchoolName(this.name);
    },
  },
};
</script>

<style scoped>
.school {
  background-color: skyblue;
  padding: 5px;
}
</style>

2.3 student.vue

<template>
  <div class="student">
    <h2>学生姓名:{{ name }}</h2>
    <h2>学生性别:{{ sex }}</h2>
    <h2>当前求和为:{{ number }}</h2>
    <button @click="add">点我number++</button>
    <button @click="sendStudentlName">把学生名给App</button>
    <button @click="unbind">解绑atguigu事件</button>
    <button @click="death">销毁当前Student组件的实例(vc)</button>
  </div>
</template>

<script>
export default {
  name: "Student",
  data() {
    return {
      name: "张三",
      sex: "男",
      number: 0,
    };
  },
  methods: {
    add() {
      console.log("add回调被调用了");
      this.number++;
    },
    sendStudentlName() {
      //触发Student组件实例身上的atguigu事件
      this.$emit("atguigu", this.name, 666, 888, 900);
      // this.$emit('demo')
      // this.$emit('click')
    },
    unbind() {
      this.$off("atguigu"); //解绑一个自定义事件
      // this.$off(['atguigu','demo']) //解绑多个自定义事件
      // this.$off() //解绑所有的自定义事件
    },
    death() {
      this.$destroy(); //销毁了当前Student组件的实例,销毁后所有Student实例的自定义事件全都不奏效。
    },
  },
};
</script>

<style lang="less" scoped>
.student {
  background-color: pink;
  padding: 5px;
  margin-top: 30px;
}
</style>

3、测试效果(略)

简单的组件间数据传递

4、实际应用(在组件化编码实战三的基础上改进)

组件化编码实战(三):https://blog.csdn.net/weixin_43304253/article/details/126256518

4.1 改进的部分说明

在这里插入图片描述

子组件中触发事件
在这里插入图片描述
在这里插入图片描述

4.2 如何查看触发的自定义事件的详细信息

在这里插入图片描述

posted on 2022-08-28 22:16  热爱技术的小郑  阅读(123)  评论(0编辑  收藏  举报