簡體   English   中英

Vue 中的渲染函數和遞歸組件

[英]Render Functions and Recursive Components in Vue

我在理解遞歸組件時遇到了一些麻煩,我相信對於我想要完成的事情,這可能是最好的方法。 這是到目前為止我所處的位置的小提琴,將在下面解釋。

https://jsfiddle.net/wp0hon7z/2/

我正在嘗試遍歷嵌套的 JSON,它基本上模仿了 DOM。 每個“節點”看起來像這樣。 您可以打開小提琴以查看更多嵌套的 JSON 和

"tagName": "section",
"classes": ["container", "mx-auto"],
"attrs": {"id":"main"},
"textNode": "",
"children": [{}]

目前,我能夠通過遞歸 go 並將每個節點創建到一個組件中,並將它們放入我在 Vue 實例中填充的組件數組中。

問題是,子組件需要顯示在父組件內。 我在想也許用組件對象創建一個 object 然后使用遞歸組件來解析這些,但我不知道如何 go 關於它。

另一個想法可能是創建一個帶有父 ID 的平面組件數組? 然后可能以某種方式使用它?

關於如何 go 的一些指導會很棒,我認為遞歸組件會有所幫助,但不確定除了創建元素/渲染函數之外我還能如何使用它。 每個節點都需要與 class 列表、屬性列表等進行 2 路綁定。我計划跟蹤這些並使用狀態/存儲進行編輯,可能是 vuex。

目前在 Fiddle 中看到的代碼將顯示 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>

您是否嘗試過按照以下方式做一些事情

// MyRecursiveComponent.vue
<template>
  <div>
    <!-- node content -->
    <div v-for="childNode" in jsonData.children">
      <MyRecursiveComponent :jsonData="childNode" />
    </div>
  </div>
<template

 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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM