子组件在渲染的过程中,先保留一部分的位置,父组件在使用子组件时再填补这部分位置(数据、其他组件)。有了插槽,我们能够更加灵活地使用组件。
slot 插槽使用方法
在子组件的内部预留一个空位slot
// 子组件
<template>
<button>
<slot></slot>
</button>
</template>
父组件使用子组件时,在子组件标签内插入内容{{text}},就会替换子组件里的<slot></slot>
// 父组件
<son>{{ text }}</son>
...
components: { son },
data() {
return { text: '正确' }
}
如果不用插槽,只能这么写:
// 父组件
<son :text="text" />
// 子组件
<template>
<button> {{ text }}</button>
</template>
...
props: ['text']
插槽的作用域
往插槽内插入的内容只能使用父组件的属性
// 父组件
<div>
<son type="big"> ok </son> <!--写法一-->
<son type="small"></son> <!--写法二-->
<son type="default"> {{ type }}</son> <!--写法三 错误-->
</div>
// 子组件
<button>
<slot>确定</slot>
</button>
...
props: ['type'],
- 写法一:插槽里传递的内容是ok,使用ok
- 写法二:没有向插槽里传递内容,因此采用默认值“确定”
- 写法三:不可以使用type,type只能在子组件里使用,我们只能用父组件的data里的属性,因此无法渲染出来
具名插槽
当子组件里有多个区域都需要父组件去不同的设计,就需要给插槽起不同的名字。
子组件内有两个具名插槽、一个普通插槽,那么该子组件内容就不是固定的,不同的父组件使用该子组件就可以向里面填充不同的内容,子组件具有了灵活性。
// 子组件
<div>
<header> <slot name="header"></slot> </header>
<main> <slot></slot> </main>
<footer> <slot name="footer"></slot> </footer>
</div>
父组件使用插槽,需要用三个template去包裹
// 父组件
<son>
<template v-slot:header>
<h1>页面的header</h1>
</template>
<template #default>
<p>页面content</p>
</template>
<template #footer>
<div>页面footer</div>
</template>
</son>
v-slot:header也可以简写成#header,默认插槽就是#default
作用域插槽
希望在父组件内能够使用子组件内的变量 item ,将变量绑定到插槽上。
// 子组件
<ul>
<li v-for="(item,index) in news">
<slot :item="item" :index="index"></slot>
</li>
</ul>
...
data() {
return {
news: ['first news', 'second news']
}
}
父组件v-slot获取子组件插槽传过来的参数
// 父组件
<son v-slot="props">第{{props.index}}章{{props.item}}</slot>