前言:
这篇文章我们一起来学习一下 Vue2 插槽的使用,文章大致分为两个模块,第一部分是什么是插槽,其作用是什么,第二部分为三种插槽的使用,分别为默认插槽,具名插槽,作用域插槽,相信大家学习完这篇文章后一定会受益匪浅
文章目录:
一:什么是插槽
例如老板要让你使用组件写分类栏,然后使用该组件生成两个分类栏,这两个分类栏里的数据都不一样,但是整体结构是一样的,这就要求组件的结构一样,但是内部 DOM 结构是由使用组件的时候决定的,这就需要插槽,其就像放在组件中的占位标签,使用组件时我们将要放到占位标签处的DOM结构写入组件标签体中即可。
例如如下图例子,第一个分类框我们要展示热门电影,第二个分类框我们要展示一张风景图,整体的框架是一样的,只是其内部填充的东西不一样下面会做出更深刻的理解。
二:默认插槽
2.1 默认插槽说明
此板块我们讲述第一个插槽:默认插槽。之前我们使用组件的时候,引入进 App.vue 后注册就可以采用 自闭合 与 完整组件标签 的方式使用,以下就是常采用的自闭合与完整组件标签方式(以 test组件为例)
<template> <test/> //自闭合方式 <test></test> //完整组件标签的方式 </template>
但是插槽的使用我们就要把要放在插槽中的内容写在组件标签体内,例如我们要在插槽中放入一个 ul 列表,那么我们使用组件时就要这样书写:
<template> <test> //组件标签 <ul> <li></li> <li></li> <li></li> </ul> </test> </template>
接下来说说默认插槽的写法,如果我们只在使用组件时的组件标签体内写上内容,那页面上是显示不出来任何东西的,这是因为标签体内的内容确实被解析了,但是vue不知道要把这些东西放在组件中 template 的哪个位置,故我们要在组件的 template 中设置一个插槽来占位,以保证使用组件时其解析的内容可以放入占的位置中去。占位我们使用一个很重要的标签 ------ slot,我们需要在组件的 template 中这样书写:
<template> <div> <span>我是一个组件,下面是我的插槽内容</span> <slot></slot> //默认插槽 </div> </template>
这样使用组件时组件标签体中的内容就可以放入组件的默认插槽中了
2.2 默认插槽使用
我们来实现一下上述的分类案例,让第一个分类展示电影,第二个分类放一张图片进去,但整体组件结构一样
classify.vue组件:
<template>
<div class="classify-box">
<div class="title">{{name}}</div>
<slot></slot> //slot设置默认插槽来占位
</div>
</template>
<script>
export default {
name:'Classify',
data() {
return {
}
},
props:['name'] //propos接收传来的标题名称
}
</script>
<style scoped>
//css太占地方就删掉了
</style>
App.vue组件:
<template>
<div class="app-box">
<Classify name='热门电影'> //使用组件并在组件标签体中书写要放进插槽中的内容
<ul>
<li>肖申克的救赎</li>
<li>1912</li>
<li>零的执行人</li>
</ul>
</Classify>
<Classify name="风景">
<img src="./img/QQ图片20220818163031.jpg" alt="">
</Classify>
</div>
</template>
<script>
import Classify from './components/classify.vue' //引入组件
export default {
name: 'App',
data() {
return {
}
},
components: {
Classify:Classify //注册组件
}
}
</script>
<style scoped>
//css太占位置删掉了
</style>
这样就可以实现一个最基本的默认插槽案例了
三:具名插槽
3.1 具名插槽说明
具名插槽其实只是在默认插槽的基础上给每个插槽起了名字,作用为可以在组件中设置多个插槽,可以更具体细分。首先给组件插槽起名字,使用 name="xxx"。
<template> <div> <span>我是一个组件,下面是我的多个具名插槽内容</span> <slot name="header"></slot> //header具名插槽 <slot name="body"></slot> //body具名插槽 <slot name="footer"></slot> //footer具名插槽 </div> </template>
上面就在组件中定义好了三个具名插槽,下面我们来看使用插槽的写法,依旧是在使用组件标签时在标签体内写入内容,但是要注意要使用 slot="xxx" 写在组件标签体外层盒子上来指明放入哪个插槽中
<template> <div class="app-box"> <Classify> <div slot="header"> //放入header插槽 <span>我在header插槽中</span> </div> <div slot="body"> //放入body插槽 <span>我在body插槽中</span> </div> <div slot="footer"> //放入footer插槽 <span>我在footer插槽中</span> </div> </Classify> </div> </template>
上面的写法其实并不完善,slot写在每个指定插槽的外层大盒子 div 上了,这样会给其增加一层 DOM 结构,我们最好把 div 换成 template 标签,因为 template 标签不会被解析,结构更清晰不多余。
3.2 具名插槽使用
下面简单实现一下具名插槽的使用
classify.vue组件:
<template>
<div class="classify-box">
<div class="title">下面是具名插槽的内容</div>
<slot name="header"></slot>
<slot name="body"></slot>
<slot name="footer"></slot>
</div>
</template>
<script>
export default {
name:'Classify',
data() {
return {
}
},
}
</script>
<style scoped>
</style>
App.vue组件:
<template>
<div class="app-box">
<Classify>
<div slot="header">
<span>我在header插槽中</span>
</div>
<div slot="body">
<span>我在body插槽中</span>
</div>
<div slot="footer">
<span>我在footer插槽中</span>
</div>
</Classify>
</div>
</template>
<script>
import Classify from './components/classify.vue'
export default {
name: 'App',
data() {
return {
}
},
components: {
Classify:Classify
}
}
</script>
<style scoped>
</style>
这样就简单实现了具名插槽
四:作用域插槽
4.1 作用域插槽说明
作用域插槽较难理解,但其简单解释就是带有数据的插槽,把组件中的数据绑定给插槽,然后谁使用这个组件谁就能拿到这个数据使用,也相当于一种数据通信,其需要这样把数据绑定定义给组件插槽(名称没有要求)
<template> <div class="classify-box"> <div class="title">下面是作用域插槽的内容</div> <slot :hobby="hobby"></slot> //将数据绑定给组件插槽 </div> </template> <script> export default { name:'Classify', data() { return { hobby:['打游戏','睡大觉','吃大餐'] //要绑定的数据 } }, } </script>
然后就要使用组件时使用 slot-scope="xxx" 去接收,或者直接使用 scope,要注意的是此处标准一点最好写在 template 中,这里的 xxx 不需要和组件插槽中起的名字一样,随便起就行。然后我们打印一下接收到的数据看看其是什么
<template> <div class="app-box"> <Classify> <template slot-scope="datas"> <div>{{datas}}</div> </template> </Classify> </div> </template>
可以看到我们接受到了一个对象,对象中包含的是你插槽中绑定的所有数据(我们只绑定了一个所以对象里只有一组数据),对此我们就能在组件标签体中使用得到的数据了
4.2 作用域插槽使用
下面简单实现一下作用域插槽的使用
classify.vue组件:
<template>
<div class="classify-box">
<div class="title">下面是作用域插槽的内容</div>
<slot :hobby="hobby"></slot>
</div>
</template>
<script>
export default {
name:'Classify',
data() {
return {
hobby:['打游戏','睡大觉','吃大餐']
}
},
}
</script>
<style scoped>
</style>
App.vue组件:
此处 slot-scope 接收的数据使用了es6解构把数据解构出来了
<template>
<div class="app-box">
<Classify>
<template slot-scope="{hobby}">
<ul>
<li v-for="(h,index) in hobby" :key="index">{{h}}</li>
</ul>
</template>
</Classify>
</div>
</template>
<script>
import Classify from './components/classify.vue'
export default {
name: 'App',
data() {
return {
}
},
components: {
Classify:Classify
}
}
</script>
<style scoped>
</style>
这样就简单实现了作用域插槽的案例
感谢支持