Vue.js回调引用而不是发出

时间:2018-03-11 11:39:37

标签: vue.js callback

在vue.js中,为了从子节点调用父节点的功能,我倾向于使用回调引用(将函数引用作为props传递)而不是使用发出。我认为使用发射更加重要,因为听众可能会减慢页面速度。这是正确的方法吗?

1 个答案:

答案 0 :(得分:2)

我继续为你设置了性能测试。

监听器明显快于回调。

每次调用10次的10个回调/监听器的比较表明,回调比听众慢5%到15%。性能的差异越大,每个回调/监听器的执行次数越多:在1000次执行时,回调的速度会慢15%到25%。

https://jsperf.com/vuejs-listener-vs-callback/

我欢迎更正,以防我犯了任何愚蠢的错误,这使得这是一个不公平的测试,但到目前为止看起来标准的$ emit / $ on模式在性能方面更适合传递回调道具。

这并不是说永远不应该使用回调 - 在某些情况下它们可能更方便,对于来自React的开发人员来说可能是更熟悉的习惯用法。但是,不要使用模糊的关于性能的担忧来证明这种偏好。

测试代码

以下是我比较的代码:

监听:

为简单起见,我在这里使用了公共事件总线模式,而不是直接在组件之间进行通信;我不相信这会对性能产生重大影响(但如果是这样可以提供更正!)

var bus = new Vue({});

Vue.component('parent', {
  template: '<div>Parent {{counter}} <child></child></div>',
  data() {return {counter: 0}},
  beforeMount() {
    // 10 listeners
    for (var i=0; i<10; i++) {
    window.bus.$on('testemit'+i, () => {
      this.counter++;
    });
    }
  }
})

Vue.component('child', {
  template: '<div>Child</div>',
  mounted() {
    // call each listener 10 times
    for (var i=0; i<10; i++) {
      for (var j=0; j<10; j++) {
        window.bus.$emit('testemit'+i);
      }
    }
  }
})

var app = new Vue({
  el: '#app'
});
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>
<div id="app">
  <parent></parent>
</div>

回调:

为了公平性,在这里设置事件总线实例以及在监听器测试中设置事件总线实例;然后它会被忽略,而不是回调道具。

var bus = new Vue({});

Vue.component('parent', {
  // 10 callback props
  template: "<div>Parent {{counter}}<child :c1='foo' :c2='foo' :c3='foo' :c4='foo' :c5='foo' :c6='foo' :c7='foo' :c8='foo' :c9='foo' :c10='foo' ></child></div>",
  data() {return {counter: 0}},
  methods: {
    foo() {
      this.counter++
    }
  }
});

Vue.component('child', {
  template: '<div>Child</div>',
  props: ["c1","c2","c3","c4","c5","c6","c7","c8","c9","c10"],
  mounted() {
    // call each callback 10 times
    for (var i=0; i<10; i++) {
      this.c1();
      this.c2();
      this.c3();
      this.c4();
      this.c5();
      this.c6();
      this.c7();
      this.c8();
      this.c9();
      this.c10();
    }
  }
})

var app = new Vue({
  el: '#app'
});
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>

<div id="app">
  <parent></parent>
</div>