简体   繁体   中英

VueJS pass prop to child without referencing child in parent template

I have 2 components Parent and Child - a parent can have many children. I need the children to know their position ( index ) in relation to their siblings.

Javascript

Vue.component('Parent', {
    template: '<div><slot></slot></div>',
    mounted: function() {
        this.$children.forEach(function(child, index) {
            /* attempt one */
            child.$el.setAttribute('test-prop', index);

            /* attempt two */
            child.$props.testProp = index;
        })
    }
})

Vue.component('Child', {
    template: '<div><span>{{testProp}}</span><slot></slot></div>',
    props: ['testProp']
});

Markup

<Parent>
    <Child>some complex html</Child>
    <Child>some complex html</Child>
    <Child>some complex html</Child>
    <Child>some complex html</Child>
</Parent>

attempt one results in undefined but dom inspector shows the property has been applied

attempt two throws a direct prop mutation warning but the child still doesn't appear to have access to the index.

The indices are only known at the point of Parent being mounted, so I can't apply the prop directly to the Child elements in the Markup.

I cannot include <Child v-for="child in children"> in the Parent template because Parent requires to be used to retrieve the Child`'s from the source HTML markup.

What would be the best way to tackle this?

The solution I have found is in the created function of the Parent component. Loop through the default slots and pass in an index to the Child VNode's componentOptions .

The code below assumes only child components and whitespace are present in the template, you can add additional checks against each slot in the foreach to ensure it is the correct component.

created: function() {
        var index = 0;
        this.$slots.default.forEach(function(slot) {
            if (slot.componentOptions !== undefined && slot.componentOptions.propsData !== undefined) {
                slot.componentOptions.propsData.testProp = index;
                index++;
            }
        })
    },

Edit: This however doesn't have reactivity - you can't data bind using this.

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