Vue中的渲染函数和递归组件

问题描述 投票:0回答:2

我在理解递归组件时遇到了一些麻烦,我相信对于我要实现的目标,这可能是最好的方法。这是我目前所处位置的小提琴,将在下面进行解释。

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

我正在尝试遍历嵌套的JSON,它实际上是模仿DOM。每个“节点”看起来都像这样。您可以打开小提琴以查看更多嵌套的JSON,

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

目前,我能够递归地遍历并将每个节点创建到组件中,并将它们放入我在Vue实例中填充的Component数组中。

问题是,子组件需要显示在父组件内部。我在想也许是用组件对象创建一个对象,然后使用递归组件来解析这些对象,但是我不知道该如何处理。

另一个想法可能是创建带有父ID的平面组件数组?然后可能以某种方式使用它?

有关如何执行此操作的一些指导非常有用,我认为递归组件将有所帮助,但不确定除创建元素/渲染功能外,如何使用它。每个节点将需要通过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> 

我在理解递归组件时遇到了一些麻烦,我相信对于我要实现的目标,这可能是最好的方法。这是我到目前为止所处的位置,...

javascript vue.js recursion vue-component vue-render-function
2个回答
0
投票


0
投票

您是否尝试过按照以下方式做某事

© www.soinside.com 2019 - 2024. All rights reserved.