插槽
插槽的基本使用
例:在组件 child.vue 中,使用 slot 标签来占位
<template>
<div>
<slot>
<h2>我是默认显示的元素</h2>
</slot>
</div>
</template>
在组件 father.vue 中,使用 child 组件
<template>
<div>
<child>
<button>我是按钮</button>
</child>
</div>
</template>
此时 child 标签里的内容会替换 child 组件里的 slot 标签
具名插槽
如果组件里面有多个插槽,可以通过 name 属性来给插槽命名,然后通过名称来替换对应的插槽
<template>
<div>
<slot name='left'></slot>
<slot name='center'></slot>
<slot name='right'></slot>
</div>
</template>
在组件 father.vue 中,使用 v-slot: 来使用具名插槽
<template>
<div>
<child>
<template v-slot:left>
<span>我是span元素</span>
</template>
<template v-slot:center>
<div>我是div元素</div>
</template>
<template v-slot:right>
<p>我是p元素</p>
</template>
</child>
</div>
</template>
动态插槽名
在组件 father.vue 中
<template>
<div>
<child>
<template v-slot:[name]>
<div>我是动态插槽名的div元素</div>
</template>
</child>
</div>
</template>
export default {
data() {
return {
name: 'tangting'
}
}
}
v-slot:可以简写成 #
作用域插槽
编译作用域
在Vue中有编译作用域的概念:
-
父级模板里的所有内容都是在父级作用域中编译的
-
子模板里的所有内容都是在子作用域中编译的
也就是说,当在父组件里使用插槽时,如果使用了数据,那么这个数据必须是在父组件中定义的,虽然它最后是渲染到子组件中。
但是在某些情况下,我们希望在插槽可以访问到子组件中的数据,这时我们就可以使用作用域插槽。
在组件 child.vue 中:
<template>
<div>
// 定义插槽的 props,用来把子组件的数据传递过去
<slot content='abc' value='123'></slot>
</div>
</template>
在组件 father.vue 中:
<template>
<div>
<child>
<template v-slot='slotProps'>
// 使用时通过 slotProps 获取到插槽的 props
<h2> {{ slotProps.content }} </h2> // abc
<h2> {{ slotProps.value }} </h2> // 123
</template>
</child>
</div>
</template>
具名插槽跟作用域插槽一起使用
在组件 child.vue 中:
<template>
<div>
// 定义插槽的 props,用来把子组件的数据传递过去
<slot name='why' content='abc' value='123'></slot>
<slot name='kobe' content='def' value='456'></slot>
</div>
</template>
在组件 father.vue 中:
<template>
<div>
<child>
<template v-slot:kobe='slotProps'>
// 使用 slotProps 获取到插槽的 props
<h2> {{ slotProps.content }} </h2> // def
<h2> {{ slotProps.value }} </h2> // 456
</template>
</child>
</div>
</template>
独占默认插槽的写法
如果在使用插槽时满足:
-
是默认的插槽
-
只有默认的插槽
那么我们就可以把组件的标签当做插槽的模板来使用,也就是说我们就可以将 v-slot 直接用在组件上