我需要创建一个动态表单,它以树的方式构建。用户(创建/设计表单的人)可以随时更改表单,因此我的输入也会动态更改。
示例:
root
--groeisnelheid
----niveau
------beginner (input radio)
------recreatief (input radio)
------competitie (input radio)
------tour (input radio)
----input text
----begeleiding
------another input
------and another
--another category
----speed
------input
------input
如您所见,这不是最简单的表单...用户(在本例中为管理员用户)能够编辑或创建新表单。
我可能低估了这份工作,因为我正在尝试创建它的输入端,并且已经在挣扎。
到目前为止我做了什么:
TreeComponent.vue
<template>
<div class="tree">
<ul class="tree-list">
<tree-node :node="treeData"></tree-node>
</ul>
</div>
</template>
<script>
export default {
props: {
treeData: [Object, Array]
},
data() {
return {
treeValues: []
};
},
methods: {
sendForm: function() {}
}
};
</script>
TreeNodeComponent.vue
<template>
<li v-if="node.children && node.children.length" class="node">
<span class="label">{{ node.name }}</span>
<ul>
<node v-for="child in node.children" :node="child" :key="child.id"></node>
</ul>
</li>
<div v-else class="form-check form-check-inline">
<input
type="radio"
class="form-check-input"
:name="'parent-' + node.parent_id"
:id="node.id"
/>
<label for class="form-check-label">{{ node.name }}</label>
</div>
</template>
<script>
export default {
name: "node",
props: {
node: [Object, Array]
}
};
</script>
这会导致所有输入都按我想要的方式显示。但现在真正的问题是;如何在根组件 (TreeComponent.vue) 中获取这些输入的值,以便将其发送到服务器。无论是在更改时还是在用户继续填写表单时。
我习惯于在这方面使用v-model
,但我不知道如何在递归组件上使用它,因为文档仅涵盖设置直接父级的数据。
任何帮助将不胜感激。
最佳答案
实现此目的的一种方法是将一个 prop 从 TreeComponent
向下传递到每个节点。
<template>
<div class="tree">
<ul class="tree-list">
<tree-node :node="treeData" :form="formRepo"></tree-node>
</ul>
</div>
</template>
然后每个节点将 prop 传递给它的子节点。
<node v-for="child in node.children" :node="child" :key="child.id" :form="form"></node>
这样每个节点都将直接引用TreeComponent
。
在每个节点中您可以 watch模型并更新 form
属性。您需要使用您的 child.id
以便知道哪个字段是哪个字段。
您的 formRepo
可以是一个完全成熟的对象,但哈希也可以发挥作用。
data() {
return {
treeValues: [],
formRepo: {
}
};
}
注意:如果您希望 formRepo
具有反应性,则需要使用 Vue.set
向其添加新键。
关于javascript - VueJS - 从递归树中获取输入值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61102687/