javascript - 如何在递归组件中出现 "Avoid mutating a prop directly"

标签 javascript vue.js vuejs2 vue-component

我理解这个概念: child 在自己的 Prop 数据副本上工作,当它被改变时,它可以 $emit这种变化,所以 parent 可以更新自己。

但是,我正在处理递归树结构,例如文件系统,是一个很好的类比。

[
 { type: 'dir', name: 'music', children: [
    { type: 'dir', name: 'genres', children: [
       { type: 'dir', name: 'triphop', children: [
          { type: 'file', name: 'Portishead' },
          ...
       ]},
     ]}
   ]}
]}

我有一个名为 Thing 的递归组件这需要 childtree Prop 看起来有点像这样:

<template>
  <input v-model="tree.name" />
  <thing v-for="childtree in tree.children" :tree="childtree" ></thing>
</template>

修改名字显然是要直接修改prop,这是要避免的,Vue会发出警告。

但是,我能看到避免这种情况的唯一方法是让每个组件对 childtree 进行深层复制。 ;然后 $emit一份我们的副本,并有一个 @input (或类似的)将其复制回原件;一直向上爬到树上,然后沿着树向下一直更改 Prop ,从而导致所有内容的另一个深拷贝!

感觉就像它在任何大小的树上都会非常低效。

有没有更好的办法?我知道你可以欺骗 Vue 不发出错误/警告 example jsfiddle .

最佳答案

解决您的问题的方法是仅从子组件传递事件。
https://jsfiddle.net/kv1w72pg/2/

<input @input="(e) => $emit('input', e.target.value)" />

话虽如此,我强烈建议您使用其他解决方案,例如:
  • Vuex,
  • 事件总线

  • 它将使代码清晰并确保一个事实来源。

    编辑:在递归继承的情况下,使用提供注入(inject)会更容易:https://jsfiddle.net/s0b9fpr8/4/

    通过这种方式,您可以提供一个函数,可以将基础组件的状态更改为所有子组件(必须注入(inject)函数)。

    关于javascript - 如何在递归组件中出现 "Avoid mutating a prop directly",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60672605/

    相关文章:

    javascript - 我的 vuejs 出现错误

    vue.js - Vue-Router:通过正确的身份验证保护私有(private)路由

    javascript - 如何使用 lodash 从对象中删除属性?

    css - 我正在尝试向我的 vue.js 元素添加背景图片

    javascript - 继续尝试重新加载图像直到成功但不显示中间损坏的图像图标

    javascript - if 语句和 vuejs 重启计数器的错误

    vue.js - 排除 json 文件被捆绑在 Vue 中

    javascript - vue.js : Filtering not working as I expect

    javascript - 如何使用 javascript 启动应用程序?

    javascript - Kendo UI Angular Grid - 只需要显示一行内容