组件的自定义事件-总结

准备

为了点击按钮时,触发太多事件,我把一些事件注释掉

将从student上获取到的数据体现在app页面上

方法一

可以通过以下这个方法来做,

这样页面点击按钮就可以在app页面上看到学生名了

方法二

通过this. <math xmlns="http://www.w3.org/1998/Math/MathML"> r e f s . x x x . refs.xxx. </math>refs.xxx.on('xuesheng',回调)绑定自定义事件时,

方式一:回调配置在methods中

上边使用的是第一种写法,我们可以使用一下第二种写法ref

这样也能实现

方式二:this.refs.xxx.on('xuesheng',回调),用箭头函数

如果我把getStudentname方法注释掉,直接在ref下写xuesheng的回调可以吗

可以看到点击按钮后,app还是可以收到数据的

我们把数据放到页面上

点击按钮后,我们可以发现页面上并没有学生名

我们先在控制台看看这个this是什么

网页上点击按钮后,我们可以发现这个this是student组件实例对象vm,所以通过这个方法并不能将学生名放到app页面上

因为是谁触发这个xuesheng方法,那么这个this就是谁,是student触发这个xuesheng,所以这个this就是student的实例对象vm。但是如果把function()改成箭头函数就行了

网页上点击按钮后我们可以发现控制台输出的this是app的实例对象,因而我们可以看到在app上的学生姓名

因为箭头函数没有this所以它就往外找,找到了app的实例对象。为了不用那么麻烦的去区分用普通函数还是箭头函数,我建议还是使用原先的那种方法吧

组件使用原生DOM事件

当作自定义事件

我们添加一个click事件试试,

然后在网页上点击student也就是粉色部分,发现没有任何反应

是因为student把click事件当成自定义事件,如果要触发需要$emit

这样在网页上需要点击上传学生名按钮,才能触发click事件

通过native,通知是原生DOM事件

那么我们要怎么告诉student,click是原生DOM事件呢?我们先把刚才的$emit注释掉

在click后面添加.native就能告诉student,click是原生DOM事件 ,然后把click事件给student最外边的div这也是为什么组件只能有一个跟元素

网页上点击粉色部分,就能触发click事件

组件自定义事件的总结

本结的主要代码如下:

MyStudent.vue

xml 复制代码
<template>
  <div class="student">
    <h1>学校姓名:{{ name }}</h1>
    <h1>学生年龄:{{ age }}</h1>
    <h1>当前求和为:{{ number }}</h1>
    <button @click="add">number++</button>
    <button @click="sendStudentname">上传学生名给App</button>
    <button @click="unbind">解绑xuesheng事件</button>
    <button @click="death">销毁当前Student组件的实例对象(vc)</button>
  </div>
</template>

<script>
// 组件交互相关的代码(数据、方法等等)
export default {
  name: "MyStudent",
  data() {
    return {
      name: "小蒲",
      age: 18,
      number: 0,
    };
  },
  methods: {
    add() {
      console.log('Dom原生事件add被调用')
      this.number++;
    },
    sendStudentname() {
      // 触发Student组件实例对象上的xuesheng事件
      this.$emit("xuesheng", this.name, 111, 222, 333);
      // this.$emit("demo");
      // this.$emit("click")
    },
    unbind() {
      this.$off("xuesheng"); //只适用解绑一个自定义事件
      // this.$off(["xuesheng", "demo"]); //只适用解绑多个自定义事件
      // this.$off(); //解绑所有自定义事件
    },
    death() {
      this.$destroy();//销毁了当前Student组件的实例,销毁后所以Student实例的自定义事件全都不奏效了
    },
  },
};
</script>

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

App.vue

xml 复制代码
<template>
  <div class="App">
    <h1>{{ msg }},学生姓名是{{ studentName }}</h1>
    <!-- <h2>{{ Schoolname }}</h2> -->
    <!-- 通过父组件给子组件传递函数类型的props实现:子给父传递数据 -->
    <School :getSchoolname="getSchoolname" />
    <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第一种写法,使用@或v-on)-->
    <!-- <Student v-on:xuesheng="getStudentname" /> -->
    <!-- <Student @xuesheng="getStudentname" @demo="m1" /> -->
    <!-- <Student @xuesheng="getStudentname" /> -->
    <!-- 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第二种写法,使用ref)-->
    <Student ref="student" @click.native="cl" />
  </div>
</template>

<script>
// 引入组件
import School from "./components/MySchool.vue";
import Student from "./components/MyStudent.vue";

export default {
  name: "App",
  components: { School, Student },
  data() {
    return {
      msg: "你好啊",
      // schoolName: "",
      studentName: "",
    };
  },
  methods: {
    cl() {
      alert("123");
    },
    getSchoolname(name) {
      console.log("App收到了学校名", name);
      // this.Schoolname = name;
    },
    getStudentname(name, ...params) {
      console.log("App收到了学生名", name, params);
      this.studentName = name;
    },
    // m1(){
    //   console.log('demo事件被触发了!')
    // }
  },
  mounted() {
    //   setTimeout(() => {
    this.$refs.student.$on("xuesheng", this.getStudentname);
    // this.$refs.student.$on("xuesheng", (name, ...params) => {
    //   console.log("App收到了学生名", name, params);
    //   console.log(this);
    //   this.studentName = name;
    // });
    //     this.$refs.student.$once("xuesheng", this.getStudentname)(一次性);
    //   }, 3000);
  },
};
</script>

<style>
.App {
  background-color: gray;
  padding: 5px;
}
</style>
相关推荐
qq_3643717230 分钟前
Vue 内置组件 keep-alive 中 LRU 缓存淘汰策略和实现
前端·vue.js·缓存
y先森1 小时前
CSS3中的弹性布局之侧轴的对齐方式
前端·css·css3
你挚爱的强哥6 小时前
✅✅✅【Vue.js】sd.js基于jQuery Ajax最新原生完整版for凯哥API版本
javascript·vue.js·jquery
y先森6 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy6 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189117 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿8 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡9 小时前
commitlint校验git提交信息
前端
天天进步20159 小时前
Vue+Springboot用Websocket实现协同编辑
vue.js·spring boot·websocket
虾球xz9 小时前
游戏引擎学习第20天
前端·学习·游戏引擎