繁体   English   中英

从子组件更新父组件的对象数组的正确方法是什么?

[英]What's the right approach to update a parent's component array of objects from a child component?

我有一个带有不同选项卡的复杂表单。 我使用vue-router在这些之间切换,并在router-view中为它们中的每一个显示不同的模块化组件。 在这些选项卡中,我有子组件,有时还有其他嵌套的子组件。 我使用event bus方法将来自这些子组件的数据向上传递到树中。 我这样做是因为最后一个选项卡将是表单的摘要,我需要访问所有表单数据。 目前我正在使用类似下面的东西。

例如使用这种结构:

|App
--|Start
--|Question 1
  --|Answer 1
  --|Answer 2
--|Question 2
...

在根组件(App)中:

data() {
  return {
    questions: 0,
    answers: []
  }
},
created() {
    eventBus.$on('answer-added', answer => {
        let answer_exists = false
        this.answers.forEach( (e, i) => {
            if(e.id == answer.answer_id) answer_exists = true
        });
        if(!answer_exists) this.answers.push({
            id: answer.answer_id,
            answer: answer.answer_text
        })
    });
}

每次触发来自孩子的事件时,在 App 组件中创建/更新/删除答案数组的正确方法是什么? 我相信肯定有比遍历数组元素更好的方法来检查答案是否已经存在......只是无法弄清楚。

你的意思是这样的:

if (!this.answers.find(a => a.id === answer.answer_id)) {
    this.answers.push(/* ... */);
}

你所做的或多或少是对的。 无法逃脱循环。 但是,您可以在某些方面进行改进。 代替forEach ,您可以使用Array.some方法 或者,您可以使用Array.find方法:

eventBus.$on('answer-added', answer => {

    // Instead of using forEach, you can use Array.some() method
    const answerExists = this.answers.some((x) => e.id == answer.answer_id);

    if (!answerExists) {
      this.answers.push({
        id: answer.answer_id,
        answer: answer.answer_text
      });
    }
});

其次,使用事件总线是没有问题的,但它一般用于兄弟或跨组件通信。 当所有组件都在同一个祖先或父层次结构中时,使用$emit事件是正确的方法。

在你的情况下,即使你有一个嵌套的组件层次结构,随着应用程序的发展,层次结构会变得非常深,你很快就会忘记事件总线的典型发布-订阅机制。 即使这意味着从中间组件重新发出相同的事件,您也应该遵循这种做法。

对于遇到相同问题的任何人,我遇到的问题都可以通过使用Simple Global Store来解决。 正如上面@Dan 所建议的那样,其他更复杂的场景可能需要Vuex

将回调从父级传递给子级。 现在他们可以自下而上地进行交流。 孩子可以传递父母可能想要的任何数据,然后父母可以收回控制权并使用其状态或关闭状态。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM