Vue笔记 - 自定义事件与事件总线

自定义事件与事件总线

1. 事件

1.1 基本使用

  • 使用 v-on:xxx@xxx 绑定事件,其中xxx是事件名

  • 事件的回调需要配置在methods对象中,最终会在vm上

  • methods中配置的函数,都是被Vue所管理的函数,this指向的是vm或组件实例对象

  • @click="demo"@click="demo($event)" 效果一致,但后者可以传递额外参数

    <div id="root">
    <button @click="showInfo1">点击获取提示信息1</button>
    <button @click="showInfo2(66,"hi",$event)">点击获取提示信息2</button>
    </div>
    
    <script>
    	const vm = new Vue({
            el:'#root',
            data:{
                name:"Jack"
            },
            method:{
                showInfo(event){
                    alert('hi')
                },
                showInfo2(String,number,event){
                    alert(String)
                }
            }
        })
    </script>
    

1.2 事件修饰符

  • prevent:阻止默认事件(常用)

  • stop:阻止事件冒泡(常用)

  • once:事件只触发一次(常用)

  • capture:使用事件的捕获模式

  • self:只有event.target是当前操作的元素才触发事件

  • passive:事件的默认行为立即执行,无需等待事件回调执行完毕

    <div id="root">
        <div class="demo1" @click="showInfo">
            <!--原来点击超链接会在提示信息后跳转,现在不会跳转-->
            <a href="https://www.baidu.com/" @click.prevent="showInfo">点击提示信息</a>
            <!--原来点击后,由于冒泡会提示两次,现在只会提示一次-->
        	<button @click.stop="showInfo">点击提示信息</button>
            <!--事件只触发一次-->
            <button @click.once="showInfo">点我提示信息</button>
            
            <!--链式修饰-->
            <button @click.once.prevent.stop="showInfo">点我提示信息</button>
        </div>
    </div>
    

1.3 键盘事件

  • Vue中常用的按键别名:

    回车 Enter 删除 delete 退出 Esc 空格 Space 换行 tab
    up down left right
  • Vue未提供别名的按键,可以使用按键原始的key值去绑定,但是注意要转为kebab-case(短横线命名)

    • 比如CAPS LOCKS键,就要书写为caps-locks
  • 系统修饰键

    系统修饰键包含:ctrl、alt、shift、meta,它们的使用方法比较特殊

    • 配合keyup使用:按下修饰键的同时,再按下其它键,随后释放其它键,事件才会被触发
    • 配合keydown使用:正常触发事件
  • Vue.config.keyCodes.自定义键名 = 键码 可以去定制按键别名

    <div id="root">
        <!--按下回车键执行showInfo1方法-->
        <input type="text" @keydown.enter="showInfo1">
        <!--同时按下ctrl键和y键执行showInfo2方法-->
        <input type="text" @keyup.ctrl.y="showInfo2">
    </div>
    

2. 自定义事件

  • 自定义事件是一种组件间通信的方式,适用于子组件传递数据给父组件

    如果子组件想给父组件传数据,那么就要在父组件中给子组件绑定自定义组件

  • 基本流程:子组件 → 子组件想传递数据给子组件 → 父组件绑定监听方法给子组件 → 子组件接收并调用监听方法,同时传参 → 父组件接收到参数,使用参数与监听方法 → 父组件

  • 绑定自定义事件

    • 方法一:在父组件中<Demo @事件名="方法名"/>

      <!--EventName是之后子组件中需要调用的事件名
      	demo是父组件中(希望子组件调用的)用于监听的方法名-->
      <Student v-on:EventName="demo"/>
      <!--简写形式-->
      <Student @EventName="demo"/>
      
    • 方法二:在父组件中this.$refs.demo.$on('事件名',回调函数)

      <Student ref="student"/>
      
      .....
      
      <script>
      ....
      mounted(){
          /*this.$refs.student是为了为了获取到student的组件实例
          $on是为了绑定,EventName是之后子组件中需要调用的事件名
          this.getStudentName是父组件中(希望子组件调用的)用于监听的方法名*/
          this.$refs.student.$on('EventName',this.getStudentName)
      }
      </script>
      
    • 注意事项

      • 通过this.$refs.xxx.$on('事件名',回调函数)绑定自定义事件时,回调函数要么配置在methods中,要么使用箭头函数,否则this指向会出问题
      • 自定义事件依旧适用事件修饰符,如<Student @EventName.once="demo"/>
      • 如果尝试在组件上绑定原生事件会产生冲突,如<Student @click="demo"/>,这样被会识别为自定义事件而无法触发click本来的效果。如果要恢复click的效果,需要使用.native<Student @click.native="demo"/>
      • 通过组件名直接绑定与通过$on没什么区别,不过$on也可以在子组件中自己调用,这样就可以自己监听自己的函数了
  • 触发自定义事件this.$emit('事件名',数据)

    • 当确定父组件已经正常绑定事件到子组件后,子组件就可以通过$emit在任意地方调用父组件的方法

    • 调用后该事件会被父组件监听到,调用时可以传递参数

      <button @click="sendStudentName">传递学生名给父组件</button>
      
      <script>
      //...
      methods:{
          sendStudentName(){
              this.$emit('atguigu',this.name)
          }
      }
      </script>
      
  • 解绑自定义事件this.$off('事件名')

    //解绑在子组件中进行
    this.$off('EventName')	//解绑单个事件
    this.$off(['EventName1','EventName2'])	//解绑多个事件
    this.$off()	//解绑所有事件
    

    注意:所有绑定的自定义事件在组件销毁时都会自动解绑

3. 全局事件总线

  • 全局事件总线是一种可以在任意组件间通信的方式,本质上是一个对象

    它满足以下要求:

    1. 所有的组件对象都必须能看见它
    2. 这个对象必须能够绑定,触发和解绑事件
  • 全局事件总线的原理与Vuex的原理有异曲同工之妙,Vuex的做法是抽离出一个js文件作为共用空间,而事件总线相对隐蔽一些——将Vue实例(vm)的原型对象上安装一个$bus作为公用空间。只要其它组件有需要,就可以用$on$bus上绑事件,然后需要回传参数的组件再用$emit传递即可

  • 安装全局事件总线

    new Vue({
        //...
        beforeCreate(){
            Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
        },
        //...
    })
    
  • 使用事件总线

    • 接收数据:若A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身

      methods(){
          demo(data){...}
      }
      //...
      mounted(){
          this.$bus.$on('xxxx',this.demo)
      }
      
    • 提供数据

      this.$bus.$emit('xxx',load)
      
posted @   Solitary-Rhyme  阅读(149)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示