前言
插槽是什么
插槽就是子组件中的提供给父组件使用的一个占位符,用<slot></slot> 表示,父组件可以在这个占位符中填充任何模板代码,这些模板代码都会替换子组件的<slot></slot> 标签。简单理解就是子组件给父组件的内容留了地方,父组件代码可以填写到子组件里面
一、默认插槽
- Vue官方规定:每一个
slot 插槽,都要有一个name 名称,如果省略了 slot 的name ,则会有一个默认名称叫做default - 默认情况下,在使用组件的时候,提供的内容都被填充到名称为
default 的插槽中
代码实例
//父页面
<template>
<div class="home">
<h1>我是-------Home----</h1>
//组件双标签写法,标签内容写入内容
<Demo>
我是插槽的内容
</Demo>
</div>
</template>
<script>
//导入组件
import Demo from '../components/demo/index.vue'
export default {
name: 'Home',
components: {
Demo
}
}
</script>
<style lang="less" scoped>
.home{
width: 60vw;
margin: 0 auto;
outline: 1px solid red;
}
</style>
//子组件
<template>
<div>
<h1>我是组件demo</h1>
<div>
//父页面嵌入的内容,通过 slot 标签展示
<slot></slot>
</div>
</div>
</template>
<style lang="less" scoped>
div{
background-color: red;
}
</style>
效果实现
二、具名插槽
什么是具名插槽
slot 后面要写上name 名称, slot 只能写在 template 和组件标签 身上- `template`` 是虚拟标签,不会渲染到节点上
- 具名插槽会将
slot 中的所有内容都将会被传入相应的插槽。任何没有被包裹在带有 slot 的 <template> 中的内容都会被视为默认插槽的内容。
应用场景
在一个组件中,我们虽然可以复用组件的结构,但是有时候会遇到一个组件多用,但是结构稍微有所差别的情况,这时,就会用得到具名插值。
代码实现
//父页面
<template>
<div class="home">
<h1>我是-------Home----</h1>
<Demo>
//slot 后面写入名称,将内容传入对应的插槽中
<template slot="head">
<p>我是头部</p>
</template>
//可使用 # 省略写法
<template #content>
<p>我是内容</p>
</template>
<template slot="footer">
<p>我是页脚</p>
</template>
</Demo>
</div>
</template>
<script>
import Demo from '../components/demo/index.vue'
export default {
name: 'Home',
components: {
Demo
}
}
</script>
<style lang="less" scoped>
.home {
width: 60vw;
margin: 0 auto;
outline: 1px solid red;
}
</style>
//子组件
<template>
<div>
<h1>我是组件demo</h1>
<div>
//接收对应的插槽内容
<slot name="content"></slot>
<slot name="footer"></slot>
<slot name="head"></slot>
</div>
</div>
</template>
<style lang="less" scoped>
div{
background-color: red;
}
</style>
效果实现
三.作用域插槽
什么是作用域插槽
- 在封装组件时,为预留的
<slot> 提供属性对应的值传递给父组件,这种用法,叫做作用域插槽 - 作用域插槽的不同之处在于,数据不在父组件身上,而是在子组件身上,但是组件的结构和内容是由父组件决定的
- 作用域插槽限制了组件内结构和数据的展示范围,以便在开发中根据业务需求而不断变化其中的数据和结构
应用场景
在一个组件中除了一个小地方显示的东西不同,其他的内容都是一样的!为了实现业务效果,有几个状态写几个组件或者直接写在页面中(不利于维护).这个时候就会用到作用域插槽
代码实现
//父页面
<template>
<div class="home">
<h1>我是-------Home----</h1>
<Demo>
//在slot后面用接收;接收的是是一个对象
<template #head="scope">
<p>我是头部 --{{ scope.head }}</p>
</template>
//解构赋值写法
<template #content="{ content, user }">
<div style="outline:1px solid red">
<p>我是内容</p>
<p>{{ content }}</p>
<p>姓名:{{ user.name }}</p>
<p>年龄:{{ user.age }}</p>
</div>
</template>
<template #footer>
<p>我是页脚</p>
</template>
</Demo>
</div>
</template>
<script>
import Demo from '../components/demo/index.vue'
export default {
name: 'Home',
components: {
Demo
}
}
</script>
<style lang="less" scoped>
.home {
width: 60vw;
margin: 0 auto;
}
</style>
//子页面
<template>
<div>
<h1>我是组件demo</h1>
<div>
<!-- 在封装组件时,为预留的<slot>提供属性对应的值,这种用法,叫做作用域插槽 -->
<slot name="head" :head="head"></slot>
<slot name="content" content="以下是子组件插槽作用域的值传递的值" :user="user"></slot>
<slot name="footer"></slot>
</div>
</div>
</template>
<script>
export default {
data () {
return {
head: '这个是一个标题',
user: {
name: '张三',
age: '18'
}
}
}
}
</script>
效果实现
总结
以上就是Vue的三种插槽的用法
- 作用域插槽的使用场景:子组件做循环展示,或者子组件的某一部分需要往外部指传递数据;多级组件嵌套的时候;这个时候作用域插槽是一个优秀的解决方案
- 作用域插槽是相对来说难理解的,需要深入理解
- 注意:vue2中仍可以使用slot与slot-scope,vue3只能使用v-slot了
|