vue3中插槽的使用
[TOC]
插槽就是子组件中的提供给父组件使用的一个占位符,用<slot></slot>
表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的<slot></slot>
标签,父组件填充的内容称为插槽内容。
- 子组件不提供插槽时,父组件填充失效
- 父组件无填充时,
<slot></slot>
中的备用内容会启用生效
- 父级模板里的所有内容都是在父级作用域中编译的,子模板里的所有内容都是在子作用域中编译的,互不影响
匿名插槽
又名默认插槽
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <!-- my-button子组件定义 --> <template> <button> <slot>SUBMIT BTN</slot> </button> </template>
<!-- 父组件调用my-button --> <my-button> 提交按钮 </my-button>
<!-- 父组件页面渲染为 --> <button> 提交按钮 </button>
|
具名插槽
当有多个插槽时,插槽增加了name
属性来正确渲染对应的部分,父组件需要使用<template></template>
。可以认为匿名插槽是特殊的具名插槽。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| <!-- my-layout子组件定义 --> <template> <div> <header> <slot name="header"></slot> </header> <main> <!-- 其实就是<slot name="default"></slot> --> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div> </template>
<!-- 父组件调用my-layout --> <my-layout> <!-- 填充内容顺序无关 --> <template v-slot:footer> <p>我来组成脚丫子</p> </template> <!-- v-slot:header可以简写为#header --> <template v-slot:header> <h1>我来组成头部</h1> </template>
<!-- v-slot:default可以忽略不写 --> <template v-slot:default> <p>我来组成身体</p> </template> </my-layout>
<!-- 父组件页面渲染为 --> <div> <header> <h1>我来组成头部</h1> </header> <main> <p>我来组成身体</p> </main> <footer> <p>我来组成脚丫子</p> </footer> </div>
|
作用域插槽
让父级插槽内容能够访问子组件数据,数据从子组件往父组件流动。子组件通过插槽prop(任意个数)来绑定数据,父组件通过带值(命名随意)的v-slot
来获取子组件的数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| <!-- todo-list子组件定义 --> app.component('todo-list', { data() { return { items: [ { "thing1":"阅读", "thing2":"看电视" }, { "thing1":"背单词", "thing2":"玩游戏" } ] } }, template: ` <ul> <li v-for="(item, index) in items"> <!-- data即插槽prop,绑定item,index也是插槽prop,绑定index,备用内容为item.thing1 --> <slot :data="item" :index="index">{{ item.thing1 }}</slot> </li> </ul> ` })
<!-- 正常用法:父组件调用todo-list --> <todo-list> <!-- 这里default就是具名插槽的用法,slotProps来接收子组件数据,命名随意 --> <template v-slot:default="slotProps"> <i class="fas fa-check"></i> <span class="green">{{ slotProps.index }} + ' - ' + {{ slotProps.data.thing2 }}</span> </template> </todo-list>
<!-- 特殊用法:只有默认插槽时,v-slot可以写在组件上 --> <todo-list v-slot:default="slotProps"> <template> <i class="fas fa-check"></i> <span class="green">{{ slotProps.index }} + ' - ' + {{ slotProps.data.thing2 }}</span> </template> </todo-list>
<!-- 特殊用法:v-slot有解构的用法 --> <todo-list v-slot:default="{index, data}"> <template> <i class="fas fa-check"></i> <span class="green">{{ index }} + ' - ' + {{ data.thing2 }}</span> </template> </todo-list>
<!-- 父组件页面渲染为 --> <ul> <li> <i class="fas fa-check"></i> <span class="green">0 - 看电视</span> </li> <li> <i class="fas fa-check"></i> <span class="green">1 - 玩游戏</span> </li> </ul>
|