我在理解递归组件时遇到了一些麻烦,我相信对于我要实现的目标,这可能是最好的方法。这是我目前所处位置的小提琴,将在下面进行解释。
https://jsfiddle.net/wp0hon7z/2/
我正在尝试遍历嵌套的JSON,它实际上是模仿DOM的。每个“节点”看起来都像这样。您可以打开小提琴以查看更多嵌套的JSON和
"tagName": "section",
"classes": ["container", "mx-auto"],
"attrs": {"id":"main"},
"textNode": "",
"children": [{}]
目前,我能够递归地遍历每个节点并将其创建到组件中,并将它们放入在Vue实例中填充的Component数组中。
问题是,子组件需要显示在父组件内部。我在想也许是用组件对象创建一个对象,然后使用递归组件来解析这些对象,但是我不知道该如何处理。
另一个想法可能是创建带有父ID的组件平面数组?然后可能以某种方式使用它?
一些有关如何执行此操作的指导会很棒,我认为递归组件会有所帮助,但不确定除Create Element / Render Function之外我该如何使用它。每个节点将需要通过2种方式与类列表,属性列表等绑定。我计划跟踪这些并使用状态/存储(可能是vuex)进行编辑。
当前在小提琴中看到的代码将显示JSON中的所有组件,但没有嵌套,因此只是一个接一个。
const jsonData = [
{
"tagName": "section",
"classes": ["container","mx-auto"],
"attrs": {},
"textNode": "",
"children": [
{
"tagName": "div",
"classes": ["flex","flex-wrap"],
"attrs": {},
"textNode": "",
"children": [
{
"tagName": "div",
"classes": ["w-1/2"],
"attrs": {},
"textNode": "Hello"
},
{
"tagName": "div",
"classes": ["w-1/2"],
"attrs": {},
"textNode": "Goodbye"
}
]
}
]
}
];
let Components = [];
let uuid = 0;
function recurse() {
recursiveInitialize(jsonData)
}
function recursiveInitialize(j) {
if (Array.isArray(j)) {
return j.map((child) => recursiveInitialize(child))
}
if (j.children && j.children.length > 0) {
initializeComponent(j)
console.log("Hi I am " + j["tagName"] + " and a parent")
j.children.forEach((c) => {
console.log("Hi I am " + c["tagName"] + " and my parent is " + j["tagName"])
recursiveInitialize(c)
});
}
else {
console.log("Hi, I dont have any kids, I am " + j["tagName"])
initializeComponent(j)
}
}
function initializeComponent(jsonBlock){
let tempComponent = {
name: jsonBlock["tagName"]+ uuid.toString(),
methods: {
greet() {
store.setMessageAction(this)
}
},
data: function() {
return {
tagName: jsonBlock["tagName"],
classes: jsonBlock["classes"],
attrs: jsonBlock["attrs"],
children: jsonBlock["children"],
textNode: jsonBlock["textNode"],
on: {click: this.greet},
ref: uuid,
}
},
beforeCreate() {
this.uuid = uuid.toString();
uuid += 1;
},
render: function(createElement) {
return createElement(this.tagName, {
class: this.classes,
on: {
click: this.greet
},
attrs: this.attrs,
}, this.textNode);
},
mounted() {
// example usage
console.log('This ID:', this.uuid);
},
}
Components.push(tempComponent);
return tempComponent
}
const App = new Vue({
el: '#app',
data: {
children: [
Components
],
},
beforeCreate() {
recurse();
console.log("recurseRan")
},
mounted() {
this.populate()
},
methods: {
populate() {
let i = 0;
let numberOfItems = Components.length;
for (i = 0; i < numberOfItems; i++) {
console.log("populate: " + Components[i])
this.children.push(Components[i]);
}
},
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<template v-for="(child, index) in children">
<component :is="child" :key="child.name"></component>
</template>
</div>
答案 0 :(得分:0)
const jsonData = [
{
"tagName": "section",
"classes": ["container","mx-auto"],
"attrs": {},
"textNode": "",
"children": [
{
"tagName": "div",
"classes": ["flex","flex-wrap"],
"attrs": {},
"textNode": "",
"children": [
{
"tagName": "div",
"classes": ["w-1/2"],
"attrs": {},
"textNode": "Hello"
},
{
"tagName": "div",
"classes": ["w-1/2"],
"attrs": {},
"textNode": "Goodbye"
}
]
}
]
}
];
let Components = [];
let uuid = 0;
function recurse() {
recursiveInitialize(jsonData)
}
function recursiveInitialize(j) {
if (Array.isArray(j)) {
return j.map((child) => recursiveInitialize(child))
}
if (j.children && j.children.length > 0) {
initializeComponent(j)
console.log("Hi I am " + j["tagName"] + " and a parent")
j.children.forEach((c) => {
console.log("Hi I am " + c["tagName"] + " and my parent is " + j["tagName"])
recursiveInitialize(c)
});
}
else {
console.log("Hi, I dont have any kids, I am " + j["tagName"])
initializeComponent(j)
}
}
function initializeComponent(jsonBlock){
let tempComponent = {
name: jsonBlock["tagName"]+ uuid.toString(),
methods: {
greet() {
store.setMessageAction(this)
}
},
data: function() {
return {
tagName: jsonBlock["tagName"],
classes: jsonBlock["classes"],
attrs: jsonBlock["attrs"],
children: jsonBlock["children"],
textNode: jsonBlock["textNode"],
on: {click: this.greet},
ref: uuid,
}
},
beforeCreate() {
this.uuid = uuid.toString();
uuid += 1;
},
render: function(createElement) {
return createElement(this.tagName, {
class: this.classes,
on: {
click: this.greet
},
attrs: this.attrs,
}, this.textNode);
},
mounted() {
// example usage
console.log('This ID:', this.uuid);
},
}
Components.push(tempComponent);
return tempComponent
}
const App = new Vue({
el: '#app',
data: {
children: [
Components
],
},
beforeCreate() {
recurse();
console.log("recurseRan")
},
mounted() {
this.populate()
},
methods: {
populate() {
let i = 0;
let numberOfItems = Components.length;
for (i = 0; i < numberOfItems; i++) {
console.log("populate: " + Components[i])
this.children.push(Components[i]);
}
},
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<template v-for="(child, index) in children">
<component :is="child" :key="child.name"></component>
</template>
</div>
答案 1 :(得分:0)
您是否尝试过按照以下方式进行操作
// MyRecursiveComponent.vue
<template>
<div>
<!-- node content -->
<div v-for="childNode" in jsonData.children">
<MyRecursiveComponent :jsonData="childNode" />
</div>
</div>
<template