我正在使用vuejs中的递归组件为自己的树视图学习这教程。因此,输入数组如下所示:
let tree = {
label: 'root',
nodes: [
{
label: 'item1',
nodes: [
{
label: 'item1.1'
},
{
label: 'item1.2',
nodes: [
{
label: 'item1.2.1'
}
]
}
]
},
{
label: 'item2'
}
]
}
<template>
<div>
...
<tree-menu
v-for="node in nodes"
:nodes="node.nodes"
:label="node.label" />
...
</div>
<template
<script>
export default {
props: [ 'label', 'nodes' ],
name: 'tree-menu'
}
</script>
因此,基本上,一个标签和一个节点子数组被传递给一个子节点。现在,我想更新或删除一个节点(例如,item1.1),但是要在最外面的数组(此处为tree
)中反映这一变化,因为我想将更新后的结构发送到服务器。我怎么才能做到这一点?如果我更改节点的标签,这将在DOM中呈现,但是tree
数组不会被更新。
发布于 2020-12-17 07:02:58
下面是如何使用.sync
修饰符递归更新:
Vue.config.devtools = false;
Vue.config.productionTip = false;
Vue.component('tree-node', {
template: `
<div style="margin-left: 5px;">
<input :value="label"
type="text"
@input="$emit('update:label', $event.target.value)" />
<tree-node v-for="(node, key) in nodes"
:key="key"
v-bind.sync="node" />
</div>
`,
props: ['label', 'nodes']
});
let tree = {
label: 'root',
nodes: [{
label: 'item 1',
nodes: [
{ label: 'item 1.1' },
{ label: 'item 1.2',
nodes: [
{ label: 'item 1.2.1' }
]
}
]
},
{ label: 'item 2' }
]
};
new Vue({
el: '#app',
data: () => ({
tree
})
})
#app {
display: flex;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<div id="app">
<div>
<tree-node v-bind.sync="tree" />
</div>
<pre v-html="tree" />
</div>
v-bind.sync="node"
是:label.sync="node.label" :nodes.sync="node.nodes"
的缩写。v-bind
将所有对象成员公开为标记的属性,从而为组件提供支持。
解决方案的另一半是将输入中的v-model
替换为:value
+ @input
上的$emit('update:propName', $event.target.value)
调用,该调用更新父程序中的.sync
-ed属性。为了概念化它,它是一个由Vue公开的DIY v-model
,因此它可以被定制(您可以决定何时调用更新以及使用什么更新)。您可以使用任何其他类型的输入替换<input>
,这取决于您要绑定/修改的内容(复选框、textarea、select或框架可能具有的任何更高级的输入包装器)。根据输入类型的不同,您需要自定义侦听器:@change
、@someCustomEvent
等.
.sync
使每件事在每个单独的层次上都是有反应的。因为所有东西都是:key
-ed,所以不会实际发生重呈现(Vue只重新呈现实际更改的DOM元素)。如果不是这样的话,输入将失去对重呈现的关注。
更新原则是:不是在子级别进行更改,而是更新父属性,该属性通过v-bind
将其发送回子属性。
这和Vuex使用的原理是一样的。而不是改变一些本地道具,您称之为存储突变,它通过getter返回并修改本地值,但是它发生在使用该存储数据的任何组件上,而不仅仅是当前存储数据。
https://stackoverflow.com/questions/65337286
复制相似问题