Get access to the v-slot value inside of the script tag

2.1k views Asked by At

I am trying to show a loading indicator which is located inside of a component that contains a slot element (lets call this the wrapper component). To do this, I have a function inside the wrapper that sets the state of the indicator based on an input boolean (setSpinnerVisible()). Now, I would like to execute this function from the component that uses this wrapper. To do this, in the parent component I use the v-slot property to get a reference to the function. I would like to be able to call this function inside the mounted() function, or from a function within methods.

However, I am not able to figure out how to do this. The only way I can think of is by passing this v-slot value into a function that is executed on an event like a button press, which works, but I also want to be able to call this method from a function that is not executed by an action in the layout (e.g. in the mounted() function).

This is (a part of) my wrapper component (the function that toggles the spinner is left out for brevity):

<template>
    <slot v-bind:setSpinnerVisible="setSpinnerVisible"></slot>
    ...
    <div class="spinner" v-show="spinnerVisible"></div>
</template>

This is (a part of) the component that uses the wrapper:

<Wrapper v-slot="{ setSpinnerVisible }">
    ...
</Wrapper>

I would like to be able to use the value of setSpinnerVisible inside the mounted function in one way or another, something like this fictional piece of code:

<script>
export default {
    mounted() {
        this.setSpinnerVisible(true)
    }
}
</script>

I am using Vue 2.6.11

1

There are 1 answers

1
Itope84 On

There are several approaches you could take.

  1. For example, you could access the parent instance and call the method you need:

    this.$parent.setSpinnerVisible()

  2. Alternatively, you could create a gateway component that uses the Wrapper, gets setSpinnerVisible and passes it as a prop to the component that needs it.

  3. You can use dependency injection. Described here: https://v2.vuejs.org/v2/guide/components-edge-cases.html#Dependency-Injection

So, in Wrapper.vue

<template>
    ...
</template>
<script>
export default {
    provide () {
        return {
            setSpinnerVisible: this.setSpinnerVisible
        }
    }
}
</script>

And in your child component:

<Wrapper>
    ...
</Wrapper>
<script>
export default {
    inject: ['setSpinnerVisible'],
    mounted() {
        this.setSpinnerVisible(true)
    }
}
</script>

The last one would be my recommended approach because it's much neater and is not anti-pattern.