组件的自定义事件-总结

准备

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

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

方法一

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

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

方法二

通过this. r e f s . x x x . refs.xxx. 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>
相关推荐
IT_陈寒3 小时前
Java中equals方法比了个寂寞?原来这才是正确的重写姿势
前端·人工智能·后端
默_笙3 小时前
🚓 分诊台与拆题术:让 RAG 学会判断和规划
前端·javascript
CopyCode3 小时前
用 AI 迁项目有多爽?我把 Webpack 迁 Vite 的全过程记下来了
前端·架构
去伪存真3 小时前
Electron 自动化发布指南:GitHub Actions 跨平台打包全纪录
前端·electron
计算机魔术师3 小时前
OpenAI智能体失控闯进美国政府网站,53张用户图片外泄背后
前端
颜进强3 小时前
14 · NestJS ExecutionContext 执行上下文:守卫、拦截器、过滤器拿到的"同一个 context",为什么能力不一样?
前端·后端·ai编程
程序员Flycan3 小时前
🚀 跨域终结者:前端代理服务器(Proxy)原理解析与配置总结
前端
怕浪猫3 小时前
顶级模型一句话,AI 写出了能玩的 QQ飞车
前端·面试·github
huakoh3 小时前
MCP 报错分不清?先看响应里是 result 还是 error
前端
呃呃呃呃ex3 小时前
10. 现代前端工程化:ES6 React 项目实战与原理解析
前端·javascript