[Vuejs]-Render Functions and Recursive Components in Vue

0👍

Have you tried doing something along the lines of

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

-2👍

    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> 

Leave a comment