Vue自定义事件原理

自定义事件的基本用法

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <div id="app">
      <Father></Father>
    </div>
    <template id="father">
      <div>
        <h1>父组件</h1>
        <p>子组件发过来的红包{{money}}</p>
        <Son @hongbao="givemoney"></Son>
      </div>
    </template>
    <template id="son">
      <div>
        <h1>子组件</h1>
        <button @click="give">给父组件发送红包</button>
      </div>
    </template>
    <script src="./vue.js"></script>
    <script>
      // 父组件
      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",
      });
    </script>
  </body>
</html>

2:事件总线

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <Dwa></Dwa>
        <Ewa></Ewa>
    </div>
    <template id="dwa">
        <div>
            <h1>大娃</h1>
            <p>二娃组件发过来的红包{{money}}</p>
        </div>
    </template>
    <template id="ewa">
        <div>
            <h1>二娃</h1>
            <button @click="give">给大娃发红包</button>
        </div>
    </template>
    <script src="./vue.js"></script>
    <script>
        // 组件
        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'
        })
    </script>
</body>

</html>

3:原理分析

// 事件中心
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)

 

 

posted @ 2023-01-07 23:24  z_bky  阅读(23)  评论(0)    收藏  举报