简体   繁体   中英

How to pass props to component in slot?

I am developing a Vue app with pimcore and twig in the backend. I have to create a component that receives the slot (another component), and render it inside, but with dynamic props.

Here is root in viani.twig.html :

<div>
    <viani-accordion>
        <viani-filter-checkbox v-slot="{filterRows}"></viani-filter-checkbox>
    </viani-accordion>
</div>

There is nothing special. viani-accordion is a parent component and the viani-filter-checkbox is a slot , which I have to render with appropriate props.

Here you can see the VianiAccordion.vue :

<template>
    <div class="wrapper">
        <AccordionTitle v-for="(item, index) in dataToRender" :item="item" :key="index">
            /*I think this is incorrect, but I'm trying to prop data that I need in viani-filter-checkbox*/         
            <slot :filter-rows="item.items"></slot>
        </AccordionTitle>
    </div>
</template>
<script>
    import AccordionTitle from './Accordion-Title';
    export default {
        name: "Viani-Accordion",

        components: {AccordionTitle},

        data() {
            return {
                dataToRender: [
                    {
                        name: 'first item',
                        items: [
                            {
                                name: 'oil olive',
                                quantity: 10,
                            },
                            {
                                name: 'subitem 2',
                                quantity: 11,
                            },
                        ]
                    },
                    {
                        name: 'second item',
                        items: [
                            {
                                name: 'subitem 1',
                                quantity: 10,
                            },
                            {
                                name: 'subitem 2',
                                quantity: 11,
                            },
                        ]
                    }
                ]
            }
        },
    }
</script>

Then I have another deeper child component Accordion-Title.vue that is responsible for rendering the slot (so I have to pass the slot through the multiple components):

<template>
    <div v-if="isOpen" class="child-wrapper">
        /*I think this is incorrect, but I'm trying to prop data that I need in viani-filter-checkbox*/
        <slot :filterRows="item.items"></slot>
    </div>
</template>
<script>
    export default {
        name: "Accordion-Title",
        props: {
            item: {
                type: Object,
                default: null
            }
        }
    }
</script>

and finally Viani-FiltersCheckbox.vue :

<template>
    <div>
        //child component which we don't need in this case
        <FilterCheckboxRow v-for="(item, index) in filterRows" :item="item" :key="index"/>
    </div>
</template>

<script>
    import FilterCheckboxRow from './FilterCheckboxRow'
    export default {
        name: "VianiFilterCheckbox",
        components: {
            FilterCheckboxRow
        },
        props: {
            //here I expect to get array to render, but got default value (empty array)
            filterRows: {
                type: Array,
                default: function () {
                    return []
                }
            },
        },
    }
</script>

So I need to pass the props ( filterRows ) to the component ( Viani-FiltersCheckbox.vue ), which is rendered as a slot. I have read this and this , but still don't get where the mistake and how to get the props I need.

It looks like you're trying to access your props through props.XXX . That's typically only done in templates for functional components . Otherwise, the props would be accessed without the props. prefix (ie, props.item.items should be item.items ).

And to pass filterRows from the scope data to the child component, declare a <template> , and then move your child into that, binding filterRows there:

<viani-accordion>
    <!-- BEFORE: -->
    <!-- <viani-filter-checkbox v-slot="{filterRows}"></viani-filter-checkbox> -->

    <template v-slot="{filterRows}">
        <viani-filter-checkbox :filterRows="filterRows"></viani-filter-checkbox>
    </template>
</viani-accordion>

编辑将范围数据传递给孩子

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