When I run the following code, I get the following results (Google Chrome running screenshot).
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>17-Learning of Scoped Slots and Named Slots</title> <style> .h1Class{ color:red; } </style> </head> <body> <div id="div_new"> <h1 class="h1Class">first set</h1> <cpn></cpn> <h1 class="h1Class">second set</h1> <cpn> <!-- first method --> <template slot="slotName" slot-scope="planallScope"> <!-- second method after Vue2.6 --> <!-- <template v-slot:slotName="planallScope" > --> <h4>{{planallScope.planall[0]}}</h4> <h4>{{planallScope.planall[1]}}</h4> <h4>{{planallScope.planall[2]}}</h4> </template> </cpn> </div> <template id="template_div"> <div> <slot v-bind:planall="plan" name="slotName"> <ul> <li v-for="item in plan"> {{ item }}</li> </ul> </slot> </div> </template> <script src="https://cdn.jsdelivr.net/npm/vue@2.7.7/dist/vue.js"></script> <script> const templateDivText = { template: '#template_div', data() { return { plan: ['C#', 'Java', 'JavaScript'] } }, } const app_new = new Vue({ el: '#div_new', components: { 'cpn': templateDivText, }, }) </script> </body> </html>
The running result is as follows:
When I use v-slot, the code is as follows:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>17-Learning of Scoped Slots and Named Slots</title> <style> .h1Class{ color:red; } </style> </head> <body> <div id="div_new"> <h1 class="h1Class">first set</h1> <cpn></cpn> <h1 class="h1Class">second set</h1> <cpn> <!-- first method --> <!-- <template slot="slotName" slot-scope="planallScope"> --> <!-- second method after Vue2.6 --> <template v-slot:slotName="planallScope" > <h4>{{planallScope.planall[0]}}</h4> <h4>{{planallScope.planall[1]}}</h4> <h4>{{planallScope.planall[2]}}</h4> </template> </cpn> </div> <template id="template_div"> <div> <slot v-bind:planall="plan" name="slotName"> <ul> <li v-for="item in plan"> {{ item }}</li> </ul> </slot> </div> </template> <script src="https://cdn.jsdelivr.net/npm/vue@2.7.7/dist/vue.js"></script> <script> const templateDivText = { template: '#template_div', data() { return { plan: ['C#', 'Java', 'JavaScript'] } }, } const app_new = new Vue({ el: '#div_new', components: { 'cpn': templateDivText, }, }) </script> </body> </html>
The running result is as follows:
So in Vue2.7, v-slot is not available, how to solve the problem?
Advertisement
Answer
Your syntax is correct, except one little detail: you can’t use camelCase for slot names.
To be fair, I don’t precisely know why, it has to do with template compilation and with the fact the slot names get parsed as element attributes in <template v-slot:slot-name"scope">
. Vue’s styling guideline does strongly advise on using kebab-case for attributes, directives and the likes, when used in templates or JSX.
However, name="slotName"
+ <template #slot-name="scope">
doesn’t seem to work for slots.
In short, name="slotName"
(+ <template #slotName="scope"
) does not work, but name="slot-name"
(+ <template #slot-name="scope"
) does.
See it working, in Vue 2.7.7
:
const templateDivText = Vue.defineComponent({ template: '#template_div', data() { return { plan: ['C#', 'Java', 'JavaScript'] } }, }) const app_new = new Vue({ el: '#div_new', components: { 'cpn': templateDivText, }, })
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.7/dist/vue.min.js"></script> <div id="div_new"> <cpn> <template #slot-name="{planall}"> <h4>{{planall[0]}}</h4> <h4>{{planall[1]}}</h4> <h4>{{planall[2]}}</h4> </template> </cpn> </div> <template id="template_div"> <div> <slot name="slot-name" :planall="plan"> <ul> <li v-for="item in plan"> {{ item }}</li> </ul> </slot> </div> </template>
Notes:
:planAll=""
is shorthand forv-bind:planAll=""
<template #slot-name="">
is shorthand for<template v-slot:slot-name="">
- when you only have one slot, you can remove the slot name altogether (it defaults to
name="default"
)