Vue2学习之路 · 八:自定义事件、全局事件总线、消息订阅与发布、$nextTick

131 阅读1分钟

自定义事件

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

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

3、绑定自定义事件

第一种方式:在父组件中

<Student @nkd="getStudentName"/>或

第二种方式:在父组件中 < Student ref="student"/>

如果想要让自定义事件只能触发一次,可以使用once修饰符,或是$once方法

mounted() {
      // 第二种:绑定自定义事件
      this.$refs.student.$on('nkd',this.getStudentName)
      // 只触发一次:绑定自定义事件(只触发一次)
      // this.$refs.student.$once('nkd',this.getStudentName);
    }

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

5、解绑自定义事件:this.$off('事件名')

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

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

全局事件总线

GlobalEventBus

1、一种组件间通信的方式,适用于任意组件间通信

2、设置全局事件总线(在vm实例中)

new Vue({
	……
  beforeCreate(){
    Vue.prototype.$bus = this;
    //设置全局事件总线,$bus就是当前应用的vm
  },
  ……
})

3、使用全局事件总线

接收数据:A组件想接收数据,就在A组件中给$bus绑定自定义事件,事件的回调留在A组件的自身中,然后让B组件触发A组件中的自定义事件并发送数据

mehtods:{
  demo(data){
    ……
  }
}
mounted() {
      this.$bus.$on('hello',(data)=>{
        //这里的回调函数可以先在methods中先定义好
        // 或者是直接在这里定义,但是直接定义的话就必须使用箭头函数
        console.log('我是school组件,收到了数据' + data)
      })
    }
  
//或
  
mehtods:{
  demo(data){
    console.log('我是school组件,收到了数据' + data)
  }
}
mounted() {
      this.$bus.$on('hello',this.demo)
}
methods:{
      sendStudentName(){
        this.$bus.$emit('hello',666)
      }
    }

4、最好在组件销毁之前,在beforeDestory钩子中,用$off去解绑所用到的事件,要不然就会占用名字,不好管理

beforeDestroy(){
      this.$bus.$off('hello')
    }

消息订阅与发布

1、一种组件间的通信的方式,适用于任意组件间通信

2、使用

安装pubsub:npm i pubsub-js

引入pubsub:import pubsub from 'pubsub-js'

3、接收数据:A组件想接收数据,就在A组件中订阅消息,订阅的回调也写在A组件中

methods: {
      demo(msgName,data){
        console.log('我是school组件,收到了数据' + data)
      }
    },
mounted(){
  this.pubId = pubsub.subscribe('hello',this.demo)
}
  
// 或
  
    mounted() {
      this.pubId = pubsub.subscribe('hello',(msgName,data)=>{
        console.log(this);
        console.log('有人发布了hello消息,hello消息的回调执行了');
        console.log('消息名是:',msgName,'\n消息传过来的数据是啊:',data);
      })
    },

  // 记得取消订阅,需要定义一个消息Id,然后使用unsubscribe(Id)	取消
beforeDestroy(){
   pubsub.unsubscribe(this.pubId);
}

4、提供数据

methods:{
      sendStudentName(){
        pubsub.publish('hello',数据)
      }
    }
//先给要触发消息发布的按钮绑定一个点击事件,然后调用sendStudentName方法,
// 在这个方法中进行消息的发布,注意要先引入pubsub-js

5、最好在beforeDestory钩子中,使用pubsub.unsubscribe(pubId)取消订阅

$nextTick-是一个生命周期钩子

1、语法:this.$nextTick(回调函数)

2、作用:在下一次DOM更新结束后执行指定的回调函数

3、什么时候用:当数据改变时,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行

handleEdit(todo){
        if(Object.prototype.hasOwnProperty.call(todo, 'isEdit')){
          todo.isEdit = true;
        }else{
          this.$set(todo,'isEdit',true)
        }
        this.$nextTick(function(){
          this.$refs.inputTitle.focus()
        }) 
      },
// 当input变为文本框时,自动获取焦点,使用$nextTick(回调函数)