vue,发射vs传递函数作为道具

时间:2018-05-25 15:11:40

标签: javascript vue.js vuejs2

我们说我有一个按钮组件,可以在其他几个组件中导入。我希望子组件不会耦合到单击按钮时发生的任何一种逻辑。因此,我希望在利用此按钮组件的各种组件中保留该逻辑。

我认为至少有两种方法可以解决这个问题。

  1. 让孩子向父母发出一个事件,然后让父母定义处理程序。

  2. 在父项中定义处理程序,并将其作为道具传递给按钮组件。

  3. 我曾经在React做过后者。对于这种情况,是否有最好的做法?

5 个答案:

答案 0 :(得分:11)

Vue哲学是道具,事件起来。第一个选项是在事件本身向父母发出(向上)然后进行处理时更接近。

同样在Vue SFC中,您还可以使用v-on(或@)为绑定属性添加前缀,该v-on(或@)将其意图描述为事件向上而不是v-bind(或:)暗示它&# 39;尽管它确实是对事件的回调,但仍然是道具。

答案 1 :(得分:5)

最佳实践

最佳做法是选项编号1.您可以在官方文档中看到此做法:https://vuejs.org/v2/guide/components.html#Sending-Messages-to-Parents-with-Events

性能

只要您在使用事件总线或作为道具传递时传递对要执行的函数的引用,您应该看到几乎没有性能差异。

使用选项编号1

的示例

您可以使用this.$emit('eventName', dataToSend, ...)将数据发送到父组件,然后将监听组件,如<my-component @eventName="yourHandler" />。然后,您就可以为每个按钮使用不同的逻辑。

我为实现此目的的多选组件创建了一个小提琴:https://jsfiddle.net/wkdL0xbc/

// HTML
<div id="app">
  <multi-choice :items="myItems" @selected="alert($event)"></multi-choice>
  <multi-choice :items="myItems" @selected="sayIsCool"></multi-choice>
</div>

// JavaScript
const multiChoice = {
    template: '<div class="multi-choice"><span v-for="item in items" @click="select(item)">{{ item }}</span></div>',
  props: ['items'],
  methods: {
    select(item) {
        this.$emit('selected', item);
    }
  }
};

new Vue({
  el: "#app",
  data() {
    return {
        myItems: [
        'Homer',
        'Marge',
        'Bart'
      ],
    }
  },
  components: {
    multiChoice: multiChoice
  },
  methods: {
    sayIsCool(item) {
        alert(item + ' is cool!')
    }
  }
})

答案 2 :(得分:3)

我仍在学习Vue.js,如果有不一致之处,我将很高兴在这里进行任何更改。


  

Vue.js 事件是回调,不是DOM事件。您可以进行验证,因为您向事件侦听器添加了自定义名称,而不是DOM事件名称(clickfocus ...),并且没有event对象传递给函数,除非您在$event调用中指定了$emit参数。

事件

专业人士

  • 对于库:减轻负担,使客户端在方法使用方面更具灵活性
  • 有用的Vue devtools事件记录
  • 允许全局侦听器(this.$root.on),尽管Vuex.js可以更好地增强它。
  • 区分语法::用于道具,@用于事件/方法

缺点

  • 缺乏明确性,更难调试(如果没有侦听器或事件名称拼写错误,则会自动失败)

道具

专业人士

  • 更明确,更具声明性,可以默认,必需,经过验证,这使它们更易于调试(运行时错误或TypeScript中的编译错误)

缺点

  • 必须包括道具验证,因此您不必在调用function()道具之前检查它是否存在(但是使用道具验证还是一个好习惯……)

结论

看起来这些方法比其他方法更具惯例和个人偏爱,尽管我认为,如果不是Vue.js文档优先考虑 events 方法,那么每个人都会很高兴仅使用道具,我认为更好

道具可以完成事件的所有工作,除了少数情况(例如$root事件侦听模式-注意Vuex.js取代了此功能,因此是首选(针对可伸缩性),其优点是更明确,可调试且易于检查。

总结自:https://forum.vuejs.org/t/events-vs-callback-props/11451

答案 3 :(得分:0)

您正在寻找“透明包装”

Vue的海关活动与本地DOM活动不同。所以你需要将.native属性附加到事件

但是如果你想在子进程上发生事件,那么你定义一个将返回的计算属性和一个侦听器对象。现在你不会

默认情况下,未定义为道具的属性将添加到视图的根元素

所以你可以设置inheritAttrs:false,然后将$ attrs绑定到子节点,然后它就成为这些属性的目标

现在您不必考虑根组件是什么。

Chris Fritz在他的7个秘密模式谈话中做了很好的解释。从21:44左右开始https://youtu.be/7lpemgMhi0k?t=21m44s

答案 4 :(得分:0)

作为一个从React迁移过来的新手,我不知道为什么@event甚至存在(或者像上面的答案一样,是标准)。我无法声明哪个events组件会$emit,但是我可以很容易地看到哪个props被传递了。通过良好的命名,我将能够知道哪个实际上是回调事件。

相关问题