How to bind on properties of a named slot

78 Views Asked by At

Referring to this link, i am trying to implement the same example of Scoped Slotsprovided in the url. as shown in the following code snippet, i created the slot named scopedSlot and specified some properties text and count:

<footer>
    <slot name="footer"></slot>
    <div>
      <slot name="scopedSlot" :text="greetingMessage" :count="1"></slot>
    </div>
</footer>

in the App.vue, i am trying to bind on the properties of the slot as shown in the following code snippet:

<template #scopedSlot v-slot="slotProps">
  {{slotProps.text}} {{ slotProps.count }}
</template>

but the latter code generates the following error on v-slot:

An element cannot have multiple 'v-slot' directives

please let me know how to correctly bind on a slot properties

App:

<template>
  <img alt="Vue logo" src="./assets/logo.png">
  <HelloWorld msg="Welcome to Your Vue.js App"/>

  <BaseLayer_0>
    <template #header>
      <h1>header</h1>
    </template>

    <template #default>
      <p>default</p>
    </template>

    <template #footer>
      <p>footer</p>
    </template>

    <template #scopedSlot v-slot="slotProps">
      {{slotProps.text}} {{ slotProps.count }}
    </template>
    
  </BaseLayer_0>

</template>

<script>
import HelloWorld from './components/HelloWorld.vue'
import BaseLayer_0 from './components/BaseLayer_0.vue'

export default {
  name: 'App',
  components: {
    HelloWorld,
    BaseLayer_0
  }
}
</script>

BaseLayer_0

<template>
  <div class="container">
    <header>
        <slot name="header"></slot>
    </header>

    <main>
        <slot></slot>
    </main>

    <footer>
        <slot name="footer"></slot>
        <div>
          <slot name="scopedSlot" :text="greetingMessage" :count="1"></slot>
        </div>
    </footer>

  

</template>

<script>

export default { name: 'BaseLayer_0',

}

image:

enter image description here

2

There are 2 best solutions below

6
Moritz Ringler On BEST ANSWER

The correct syntax is

<template #scopedSlot="slotProps">

or

<template v-slot:scopedSlot="slotProps">

The # is shorthand for v-slot:, so in your initial code, you were assigning to the scopedSlot without using slotProps, and then again to the default slot, this time using slotProps, and Vue complained.

0
Walens On

Firstly, in BaseLayer_0.vue, in the

<slot name="scopedSlot" :text="greetingMessage" :count="1"></slot> section,

you used the shorthand : for v-bind to bind the text attribute. Therefore, greetingMessage is treated as a variable, but you haven't declared the greetingMessage variable in the script.

Hence, you need to add the following:

#BaseLayer_0.vue

<script>
export default { 
  name: 'BaseLayer_0',
  data() {
    return {
      greetingMessage: 'hello word'
    }
  }
}
</script>

Secondly, in the following code snippet, there is also an issue:

#app.vue

<template #scopedSlot v-slot="slotProps">
   {{slotProps.text}} {{ slotProps.count }}
</template>

It should be corrected to:

<template #scopedSlot="{ text, count }">
   {{ text }} {{ count }}
</template>

codesandbox demo