Vue2基础篇-28-自定义事件

1. 简介

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

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

  3. 绑定自定义事件:

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

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

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

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

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

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

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

2. demo

2.1 App

<template>
  <!DOCTYPE html>
  <html lang="en">
    <head>
      <meta charset="utf-8" />
      <title>React App</title>
      <link rel="stylesheet" href="index.css" />
    </head>
    <body>
      <div id="root">
        <div class="todo-container">
          <div class="todo-wrap">
            <!-- 通过父组件给子组件传递函数类型的props实现: 子给父传递数据 -->
            <School :sendSchoolName="sendSchoolName" />
            <hr />

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

            <Student @atDingDong="getStudentName" />
            <hr />
            <h2>学生姓名是{{ StudentName }}</h2>
            <!-- 通过父组件给子组件绑定一个自定义事件实现: 子给父传递数据(第二种写法,使用ref) -->
            <!-- <Student ref="student" /> -->

            <!-- 如果给组件绑定原生事件,比如绑定Click,那么都会当成自定义事件,除非加上修饰符native -->
            <Student ref="student" @click.native="sendClick" />
          </div>
        </div>
      </div>
    </body>
  </html>
</template>

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

export default {
  name: "App",
  data() {
    return {
      StudentName: "",
    };
  },
  components: { School, Student },
  methods: {
    sendClick() {
      console.log("给Student组件绑定原生事件");
    },
    sendSchoolName(name) {
      console.log(name);
    },
    getStudentName(name, ...params) {
      console.log(name);
      this.StudentName = name;
    },
    // getStudentName2() {
    //   console.log("getStudentName2 被触发了");
    // },
  },
  mounted() {
    this.$refs.student.$on("atDingDong", this.getStudentName);
    //谁触发的绑定事件,this就是谁,由于这里是Student组件触发的,所以这里this就是Student,所以下面这种给StudentName赋值就不行
    // this.$refs.student.$on("atDingDong", function getStudentName() {
    //   console.log(name);
    //   this.StudentName = name;
    // });

    //下面这种写法,使用的是=> ,由于=> 没有自己的this,于是他向外找,外面是App的vc,于是就可以
    // this.$refs.student.$on("atDingDong", (name, ...params) => {
    //   console.log(name);
    //   this.StudentName = name;
    // });
  },
};
</script>

<style>
/*base*/
body {
  background: #fff;
}

.btn {
  display: inline-block;
  padding: 4px 12px;
  margin-bottom: 0;
  font-size: 14px;
  line-height: 20px;
  text-align: center;
  vertical-align: middle;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),
    0 1px 2px rgba(0, 0, 0, 0.05);
  border-radius: 4px;
}

.btn-danger {
  color: #fff;
  background-color: #da4f49;
  border: 1px solid #bd362f;
}

.btn-danger:hover {
  color: #fff;
  background-color: #bd362f;
}

.btn:focus {
  outline: none;
}

.todo-container {
  width: 600px;
  margin: 0 auto;
}
.todo-container .todo-wrap {
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 5px;
}
</style>

2.2 Student

<template>
  <div>
    <h2>学生名称为{{ StudentName }}</h2>
    <h2>学生地址为{{ StudentAddress }}</h2>
    <button @click="sendName">将学生名称交给App</button>
    <button @click="unBindAtDingDong">解绑AtDingDong事件</button>
    <button @click="death">点我销毁当前实例</button>
  </div>
</template>

<script>
export default {
  name: "Student",
  data() {
    return {
      StudentName: "张三",
      StudentAddress: "金桥",
    };
  },
  methods: {
    sendName() {
      // 触发Student组件身上的atDingDong事件
      this.$emit("atDingDong", this.StudentName);
      // this.$emit("atDingDong2", this.StudentName);
    },
    unBindAtDingDong() {
      //解绑单个事件
      // this.$off('atDingDong')
      //解绑多个事件
      // this.$off(['atDingDong','atDingDong2'])

      //解绑所有事件
      this.$off();
    },
    death() {
      //销毁了当前Student组件的实例,销毁后Student的VC身上的所有的自定义事件全部失效
      this.$destroy();
    },
  },
};
</script>

<style></style>

2.3 js

<template>
  <div>
    <h2>学校名称为{{ SchoolName }}</h2>
    <h2>学校地址为{{ SchoolAddress }}</h2>
    <button @click="sendName">将学校名称交给App</button>
  </div>
</template>

<script>
export default {
  name: "School",
  props:['sendSchoolName'], 
  data() {
    return {
      SchoolName: "叮咚大学",
      SchoolAddress: "张江",
    };
  },
  methods:{
    sendName(){
      this.sendSchoolName(this.SchoolName)
    }
  }
};
</script>

<style></style>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alan0517

感谢您的鼓励与支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值