简体   繁体   中英

createElement function of vue js doesn't return compeletly component

There is a situation which is I need to write a functional component for a specific cause. That is gets all of its children and adds some props to them. But the point is, I need to add those props to just a specific custom components which are of type ChildComponent . I went this way:


MyHigherOrderComponent.vue

    render: function(createElement, context){
        const preparedChildrenLevel1 = context.children.map(child => {
            if(child.componentOptions.tag !== "ChildComponent"){
                return child;
            }

            return createElement(
                ChildComponent,
                {
                    props: {
                        ...child.componentOptions.propsData,
                        level1: "level1"
                    }
                },
                child.componentOptions.children
            )
        });
    },

This actually works fine. Then I want to use preparedChildrenLevel1 to map throw it and add another prop to the children which are of type ChildComponent . But this time I get undefined from child.componentOptions.tag .


MyHigherOrderComponent.vue

    render: function(createElement, context){
        //First level of adding props to children
        const preparedChildrenLevel1 = context.children.map(child => {

            //In here child.componentOptions.tag is equal to 'ChildComponent'
            if(child.componentOptions.tag !== "ChildComponent"){
                return child;
            }

            return createElement(
                ChildComponent,
                {
                    props: {
                        ...child.componentOptions.propsData,
                        level1: "level1"
                    }
                },
                child.componentOptions.children
            )
        });

        //Socond level of adding props to children
        const preparedChildrenLevel2 = preparedChildrenLevel1.map(child => {

            //In here child.componentOptions.tag is equal to 'undefined'
            if(child.componentOptions.tag !== "ChildComponent"){
                return child;
            }

            return createElement(
                ChildComponent,
                {
                    props: {
                        ...child.componentOptions.propsData,
                        level2: "level2"
                    }
                },
                child.componentOptions.children
            )
        });
    },

I need to get this specific type of components in many levels.


Note: Here is my complete implementation of component and how I use it

MyHigherOrderComponent.vue

<script>
export default {
    name: "MyHigherOrderComponent",

    functional: true,

    render: function(createElement, context){
        //First level of adding props to children
        const preparedChildrenLevel1 = context.children.map(child => {

            //In here child.componentOptions.tag is equal to 'ChildComponent'
            if(child.componentOptions.tag !== "ChildComponent"){
                return child;
            }

            return createElement(
                ChildComponent,
                {
                    props: {
                        ...child.componentOptions.propsData,
                        level1: "level1"
                    }
                },
                child.componentOptions.children
            )
        });

        //Socond level of adding props to children
        const preparedChildrenLevel2 = preparedChildrenLevel1.map(child => {

            //In here child.componentOptions.tag is equal to 'undefined'
            if(child.componentOptions.tag !== "ChildComponent"){
                return child;
            }

            return createElement(
                ChildComponent,
                {
                    props: {
                        ...child.componentOptions.propsData,
                        level2: "level2"
                    }
                },
                child.componentOptions.children
            )
        });
    },
}

</script>




App.vue

<template>
    <MyHigherOrderComponent>
        <p>child1</p>
        <p>child2</p>
        <ChildComponent :level0="level0">child3</ChildComponent>
        <p>child4</p>
        <ChildComponent :level0="level0">child5</ChildComponent>
        <ChildComponent :level0="level0">child6</ChildComponent>
    </MyHigherOrderComponent>
</template>

When the element is not a ChildComponent there is no child.components in it so you should add another check in the conditions:

if(!child.componentOptions || child.componentOptions.tag !== "ChildComponent") {
    return child;
}

This way it will ensure that only a ChildComponent is allowed into the rest of your code.
And by the way you're not returning anything in MyHigherOrderComponent 's render function

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM