前端高频面试题系列之第7题

前端高频面试题系列之第7题

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情

Vue自定事件的原理

  1. 基本用法

     vm.$emit('自定义事件的名称',this.data) // 触发事件
     vm.$on('自定义事件的名称',function(data){}) // 监听事件
    复制代码

    注意:

    如果是子到父通信 不能用 $on 侦听子组件抛出的事件,而必须在模板里直接用 v-on 绑定。 ​ 就是父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。

    // 父组件
        Vue.component('Father', {
            template: '#father',
            data() {
                return {
                    money: 0
                }
            },
            methods: {
                givemoney(sonmoney) {
                    this.money = sonmoney
                }
            }
        })
        // 子组件
        Vue.component('Son', {
            template: '#son',
            data() {
                return {
                    money: 3000
                }
            },
            methods: {
                give() {
                    this.$emit('hongbao', this.money)
                }
            }
        })
        let vm = new Vue({
            el: '#app'
        })
    复制代码
    // 组件
      Vue.component('Dwa', {
          template: '#dwa',
          data() {
              return {
                  money: 1000
              }
          },
          methods: {
    
          },
          mounted() {
              this.$on('hongbao', (money) => {
                  console.log(money)
              })
              this.$emit('hongbao', this.money)
          }
    
      })
      // 组件
      Vue.component('Ewa', {
          template: '#ewa',
          data() {
              return {
                  money: 3000
              }
          },
          methods: {
              give() {
                  Bus.$emit('hongbao', this.money)
              }
          }
      })
      // 事件总线
      let Bus = new Vue()
    
      let vm = new Vue({
          el: '#app'
      })
    复制代码
  2. 实现原理

    • 子父通信原理 (观察者模式)

    • 事件总线原理 (发布订阅者模式)

    on只能监听同一个Vue实例上emit出来的事件,事件总线就是靠这个机制实现数据传递的。

    但是父子组件是独立的Vue实例, 所以emit的事件,如果不在使用它的时候监听这个自定义事件,

    在父组件里面如果用on是监听不到的, 但是可以在一个组件里面通信(至今没发现有什么用)

    // 事件中心
        vm._events = {
            a: [fn],
            b: [fn, fn]
        }
        Vue.prototype.$on = function (event, fn) {
            var vm = this;
            if (Array.isArray(event)) {
                for (var i = 0, l = event.length; i < l; i++) {
                    vm.$on(event[i], fn);
                }
            } else {
                (vm._events[event] || (vm._events[event] = [])).push(fn);
            }
            return vm
        };
    
        Vue.prototype.$emit = function (event) {
            var vm = this;
            var cbs = vm._events[event]; // 根据事件名找对应数组也是回调集合
            if (cbs) {
                var args = toArray(arguments, 1);
                for (var i = 0, l = cbs.length; i < l; i++) {
                    cbs[i].apply(vm, args)
                }
            }
            return vm
        };
        // 监听事件
        vm.$on(['a', 'b'], function (data) {
            // data是传过来的数据
        })
        vm.$on('b', function (data) {
            // data是传过来的数据
        })
        // 触发事件
        vm.$emit('b', this.data)
    复制代码

    本文视频对应 前端大厂高频面试题, 除此之外,如果你对技术有像一素的偏执,欢迎加我vx:15910703837一起学习一起进步。

分类:
前端
标签: