【Vue】组件自定义事件 & TodoList 自定义事件数据传输

目录

一、绑定

二、解绑

组件自定义事件总结

TodoList案例对数据传输事件的修改

[总结不易~ 本章节对我有很大收获, 希望对你也是!!!](#总结不易~ 本章节对我有很大收获, 希望对你也是!!!)


本章节素材已上传Gitee:yihaohhh/我爱Vue - Gitee.com

前面我们学习的clikc、keyup......等一系列为js内置的事件(给HTML元素用的),现在我们就要学习组件的自定义事件(给组件用的!)!

一、绑定

现在想一个问题,把子元素传给父元素有几种办法!

按照我们的进度, 现在只会通过props方法来得到App的函数然后进行传参这一种办法进行

那么现在就来介绍第二种办法:组件自定义事件_绑定

  • v-on:事件名="方法" 就是监听子组件触发的自定义事件。这个事件得由子组件用 $emit('事件名') 发出来。
  • 给谁绑定事件 就找谁触发 给Student组件的实例对象
  • 通过父组件给子组件绑定一个自定义事件实现:子给父传递数据 (第一种写法 使用@或者v-on)
html 复制代码
    <!-- <Student v-on:atwhuc="getStudentName"/> -->
    <Student @atwhuc="getStudentName"/>

大白话就是:"你每次喊一声 atwhuc,我就立刻执行 getStudentName() 这个方法。你喊一次我就干一次,喊十次我就干十次。" 这个事件绑定在Student组件上

Student组件:

html 复制代码
<template>
  <div class="student">
    <h1>{{ msg }}</h1>
    <h2>学生姓名:{{ name }}</h2>
    <h2>学生性别:{{ sex }}</h2>
    <button @click="sendStudentName">把学生名给App</button>
  </div>
</template>

<script>
export default {
  name:'Student',
  data() {
    return {
      msg:'我是一个武汉传媒学院的学生',
      name:'张三',
      sex: '男' 
    }
  },
  methods: {
    sendStudentName() {
      // 触发Student的实例身上的atwhuc事件 
      // 该事件被触发 就让给方法传入了
      this.$emit('atwhuc', this.name, 666, 888, 999)
    }
  }

}
</script>

<style scoped>
  .student {
    background-color: orange;
    padding: 5px;
    margin-top: 30px;
  }
</style>

这一种写法是通过在子组件中触发 $emit('atwhuc', 数据) 来发送一个自定义事件 'atwhuc',父组件通过 @atwhuc="方法" 监听这个事件,从而实现父子组件之间的传值和通信

在子组件中用 $emit 是在向父组件发消息,这条消息就叫"自定义事件"。 有通知的意思

📌 补充说明(理解更深一点):

  • 子组件不需要知道父组件的具体方法名,只管发事件(松耦合)。

  • 父组件监听这个事件并调用自己的方法,同时可以接收 $emit 传来的数据。

但是这么直接用,有点局限性,我们可以更灵活一点!

通过父组件给子组件绑定一个自定义事件实现:子给父传递数据 (第二种写法 使用ref)

html 复制代码
    <Student ref="student"/>
javascript 复制代码
  methods: {
    getSchoolName(name) {
      console.log('App收到了学校名', name)
    },
    getStudentName(name, ...params) {
      // params 是一个数组
      console.log('App被调用!', name, params)
    }
  },  
// 放一个生命周期钩子
    mounted() {
    // 灵活性强 
    setTimeout(() => {
      this.$refs.student.$on('atwhuc', this.getStudentName)
    }, 3000)

    this.$refs.student.$on('atwhuc', this.getStudentName) // 绑定自定义事件
    
    // 只触发一次
    this.$refs.student.$once('atwhuc', this.getStudentName) // 绑定自定义事件(一次性)

  }

this.$refs.student:

  • 就是你在 HTML 里写的 <Student ref="student" />,
  • 相当于你给这个组件起了个小名,方便后面找到它。

$on 当......时:

  • $on('atwhuc', this.getStudentName):
  • 是你在监听这个组件有没有"发出"一个叫 atwhuc 的信号。
  • 如果发了,那就去执行 getStudentName 这个方法。

二、解绑

对于事件的解绑 也是通过实践绑定来通过函数调用完成!

html 复制代码
    <button @click="unbind">解绑atwhuc事件</button>
javascript 复制代码
    unbind() {
      this.$off('atwhuc') // 只适用于解绑一个自定义事件
      // emitter.off 代替 $off
      // $on	emitter.on
      // $emit	emitter.emit
    }

可以发现this.$off 只能进行单个事件的解绑

解绑多个事件,用一个数组进行存储事件!

javascript 复制代码
    this.$off(['atwhuc', 'demo']) 

更暴力的办法, 全部都解绑!

javascript 复制代码
      this.$off() // 全部都解绑 

销毁当前组件的全部实例

html 复制代码
    <button @click="death">销毁当前Student组件的实例(vc)</button>
javascript 复制代码
    death() {
      this.$destroy() // 销毁了当前的组件实例 销毁后 所有Student实例的自定义事件全都不奏效了
    }

本章节素材已上传Gitee:yihaohhh/我爱Vue - Gitee.com

组件自定义事件总结

想要把Student子组件的name传给父组件 可以用函数来接受Student的name值, 然后更新App组件的studentName的值

这是可行的!

html 复制代码
<h1>{{ msg }}, 学生姓名是:{{ studentName }}</h1>
javascript 复制代码
    getStudentName(name, ...params) {
      // params 是一个数组
      console.log('App被调用!', name, params),
      this.studentName = name
    },
javascript 复制代码
    this.$refs.student.$on('atwhuc', function(name, ...params) {
      console.log('App被调用!', name, params),
      this.studentName = name
    }) // 绑定自定义事件

用ref也是可行的!

html 复制代码
    <Student ref="student"/>
    
    mounted() {
    this.$refs.student.$on('atwhuc', this.getStudentName) // 绑定
    }

但是当我们将getStudentName注释掉之后直接在生命周期钩子里面写回调函数发现this.studentName却不能被赋值了!

javascript 复制代码
    this.$refs.student.$on('atwhuc', function(name, ...params) {
      console.log('App被调用!', name, params),
      this.studentName = name
    }) // 绑定自定义事件

点击后不起作用,但是控制台仍然会被执行!

那么我们就重新对this进行打印,来进行观察!

javascript 复制代码
    this.$refs.student.$on('atwhuc', function(name, ...params) {
      console.log('App被调用!', name, params),
      console.log(this)
      this.studentName = name
    }) // 绑定自定义事件

能够发现这些都是Student组件中才存在的, 只能说明 这个this就不是指向App组件的this ,而是Student组件的this

说明Vue的底层就是说明谁触发了'atwhuc'这个事件, 那么这个事件的回调就会指向谁

那么就说明当我们写成箭头函数的时候:这个this就又重新回到了App组件上

javascript 复制代码
    this.$refs.student.$on('atwhuc', (name, ...params)=> {
      console.log('App被调用!', name, params),
      console.log(this)
      this.studentName = name
    }) // 绑定自定义事件

那么组件可以用自定义事件,能不能用原生事件呢???点击事件呢??

html 复制代码
    <Student ref="student" @click="show"/>
javascript 复制代码
    show() {
      alert(123)
    }

可以发现其实并没效果! 原因就是这么写Vue就自动默认把click当作是一个自定义事件,要触发自定义事件,就必须要在Student组件上用$emit,就会进行触发了!

javascript 复制代码
    sendStudentName() {
      // 触发Student的实例身上的atwhuc事件 
      // 该事件被触发 就让给方法传入了
      this.$emit('atwhuc', this.name, 666, 888, 999)
      this.$emit('demo') // 自定义事件名
      this.$emit('click')
    },

那么我们只需要添加一个修饰符,就可以让Vue明白我们这是一种原生事件, .native

html 复制代码
    <Student ref="student" @click.native="show"/>
  1. 一种组件间通信的方式,适用于:<strong style="color:red">子组件 ===> 父组件</strong>

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

  3. 绑定自定义事件:

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

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

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

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

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

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

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

本章节素材已上传Gitee:yihaohhh/我爱Vue - Gitee.com

TodoList案例对数据传输事件的修改

对于子组件给父组件进行数据传输,就可以不在需要用props来传递一个函数,然后进行数据传输, 可以直接采用$emit来触发父组件的自定义事件

那么同理,框起来的全部都是传入的函数, 都是可以将props改写为emit来进行数据传输,而todos是一个数据不能修改为函数进行传递,就不能用emit来进行修改

都可以换种方式来获取自定义事件~

总结不易~ 本章节对我有很大收获, 希望对你也是!!!

相关推荐
源码云商7 分钟前
基于 SpringBoot + Vue 的校园管理系统设计与实现
vue.js·spring boot·后端
几度泥的菜花10 分钟前
Vue 项目中二维码生成功能全解析
javascript·vue.js·ecmascript
筱歌儿1 小时前
小程序问题(记录版)
前端·小程序
火龙谷2 小时前
【爬虫】码上爬第6题-倚天剑
开发语言·javascript·爬虫
Jinuss2 小时前
源码分析之Leaflet中的LayerGroup
前端·leaflet
赶飞机偏偏下雨2 小时前
【前端笔记】CSS 选择器的常见用法
前端·css·笔记
LuckyLay3 小时前
AI教你学VUE——Deepseek版
前端·javascript·vue.js
我是哈哈hh3 小时前
【Vue】全局事件总线 & TodoList 事件总线
前端·javascript·vue.js·vue3·vue2
liuyang___3 小时前
vue3+ts的watch全解!
前端·javascript·vue.js