【发布时间】:2020-03-13 14:51:55
【问题描述】:
我理解这个概念:孩子使用自己的道具数据副本,当它发生更改时,它可以$emit 进行更改,以便父母可以更新自己。
但是,我正在处理递归树结构,例如一个文件系统,是一个很好的类比。
[
{ 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(或类似的)将其复制回原件;一直到树上,然后会一直更改树下的道具,从而导致所有内容的另一个深层副本!
这感觉在任何大小的树上都会非常低效。
有没有更好的方法?我知道你可以欺骗 Vue 不发出错误/警告example jsfiddle。
【问题讨论】:
-
在你的例子中,'trick' 是可以的,而'normal' 不是,正是因为这个警告背后的原因;组件更新时会覆盖一个道具。双向数据流('trick' 中的 v-model)可能会大规模地对您不利。单向数据流($emit 或 Vuex)通常更可取。
标签: javascript vue.js vuejs2 vue-component