Vue学习笔记(22)-Vue中的插槽
Vue中的插槽
- 我们已经了解到父组件是可以通过 props 将数据传给子组件的,它可以是任何类型的 JavaScript 值。但是 模板内容(html片段)呢?在某些情况下,我们可能希望将模板片段传递给子组件,并让子组件在其自己的模板中渲染该片段,由此引出 插槽。
- slot(插槽)是 vue 为 组件的封装者 提供的能力。允许开发者在封装组件时,把 不确定的、希望由用户指定的部分 定义为插槽(即父组件向子组件传递带数据的标签,当一个子组件有不确定的结构时,就需要用到插槽了[slot])。可以把插槽认为是组件封装期间,为用户预留的内容的占位符。 注意:插槽内容是在父组件中编译后,在传递给子组件的.
作用:
- 作用:一般用于让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于 父组件 ===> 子组件 。
图解:
插槽的分类:
1.默认插槽(简单)
- 通常来说我们组件中内的标签是无法放任何外部组件内容的,如果想子组件中的内容, 由外部的组件来决定我们可以使用默认插槽,在组件内声明 slot 标签
代码解析:
- App父组件(省略css样式)
<template>
<div class="container">
<Category title = '美食'>
<img src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
</Category>
<Category title = '游戏'>
<ul>
<li v-for="(item,index) in games" :key="index">{{item}}</li>
</ul>
</Category>
<Category title = '电影'>
<video controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
</Category>
<Category title = '测试插槽默认值'/>
</div>
</template>
<script>
// 引入组件
import Category from './components/Category'
export default {
name:'App',
// 注册组件
components:{Category},
data() {
return {
foods : ['青菜','牛肉','猪肉','鸡肉'],
games : ['CSGO' , 'Apex' , 'Raionbow Six'],
films : ['让子弹飞','功夫','天下无贼','明日战记']
}
},
}
</script> - Category子组件(省略css样式)
<template>
<div class="Category">
<h3>{{title}}</h3>
<!-- 定义一个插槽(slot就是插槽的入口) -->
<!-- 不写的话你在App组件中写的结构体是即便是被解析了也不会显示 -->
<slot>这是插槽的默认值,如果没有东西填入就会显示这段文字</slot>
</div>
</template>
<script>
export default {
name : 'Category',
// 接收父组件(App)传过来的数据(美食,电影,游戏等数据,以及标题)
props : ['title']
}
</script>
结果展示:
2.具名插槽(简单)
- 具名插槽,顾名思义就是给这个插槽起个名字,插槽在使用 name 属性绑定名字后, 在组件被调用的时候,组件内的标签通过 slot 属性来决定某个标签具体渲染哪一个插槽
代码解析:
- App父组件(省略css样式)
<template>
<div class="container">
<Category title = '美食'>
<!-- 给结构体赋予slot属性用于指定解析过后插入位置(slot标签) -->
<img slot="center" src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
<a slot="footer" href="#">更多美食</a>
</Category>
<Category title = '游戏'>
<ul slot="center">
<li v-for="(item,index) in games" :key="index">{{item}}</li>
</ul>
<div class="foot" slot="footer">
<a href="#">单机游戏</a>
<a href="#">网络游戏</a>
</div>
</Category>
<Category title = '电影'>
<video slot="center" controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video>
<!-- Vue2.6新特性,使用 template标签可以使用 v-slot:footer 代替 slot="footer"-->
<template v-slot:footer>
<div class="foot">
<a href="#">经典</a>
<a href="#">热门</a>
<a href="#">推荐</a>
</div>
<h4>欢迎前来观影</h4>
</template>
</Category>
<Category title = '测试插槽默认值'/>
</div>
</template>
<script>
// 引入组件
import Category from './components/Category'
export default {
name:'App',
// 注册组件
components:{Category},
data() {
return {
foods : ['青菜','牛肉','猪肉','鸡肉'],
games : ['CSGO' , 'Apex' , 'Raionbow Six'],
films : ['让子弹飞','功夫','天下无贼','明日战记']
}
},
}
</script> - Category子组件(省略css样式)
<template>
<div class="Category">
<h3>{{title}}</h3>
<!-- 定义一个插槽(slot就是插槽的入口) -->
<!-- 不写的话你在App组件中写的结构体是即便是被解析了也不会显示 -->
<!-- 这里给插槽设置一个name属性用于指定标签内结构体二第插入位置 -->
<slot name="center">这是插槽的默认值,如果没有东西填入就会显示这段文字1(center插槽)</slot><br><br>
<slot name="footer">这是插槽的默认值,如果没有东西填入就会显示这段文字2(footer插槽)</slot>
</div>
</template>
<script>
export default {
name : 'Category',
// 接收父组件(App)传过来的数据(美食,电影,游戏等数据,以及标题)
props : ['title']
}
</script>
结果展示:
3.作用域插槽(较为拗口,难理解)
- 要想了解作用域插槽, 先了解需求之后比较好理解: 有时候数据在子组件中,但是却想让父组件来决定具体怎么展示,这里是:数据在子组件(这里的Category组件即子组件)的自身,但根据数据生成的结构需要组件的使用者(App组件即父组件)来决定。(games数据在Category组件中,但使用数据所遍历出来的结构由App组件决定)
- 这时候我们可以通过作用域插槽, 让子组件通过属性绑定的方式,把子组件的数据绑定到子组件中的某个属性上
- 父组件就可以通过slot-scope = slot拿到子组件中挂载在插槽中的数据,之后通过 比如 slot.attribute 来得到具体的数据(ps: elementui 中的表格就是使用的作用域插槽)
- 注意在父组件中,如果要拿到子组件通过属性绑定在插槽中的数据需要使用 template 标签
代码解析:
- App父组件(省略css样式)
<template>
<div class="container">
<Category title = '游戏'>
<!-- 作用与插槽要配合 template标签来使用 -->
<!-- slot-scope="yx" 这里的属性值可以随意取 -->
<!-- 当然也可以填入name属性来指定插入位置(具名插槽) -->
<template slot-scope="yx">
<ul>
<li v-for="(item,index) in yx.games" :key="index">{{item}}</li>
</ul>
</template>
</Category>
<Category title = '游戏'>
<template slot-scope="yx">
<ol>
<li v-for="(item,index) in yx.games" :key="index">{{item}}</li>
</ol>
</template>
</Category>
<Category title = '游戏'>
<template slot-scope="yx">
<h4 v-for="(item,index) in yx.games" :key="index">{{item}}</h4>
</template>
</Category>
<Category title = '测试插槽默认值'/>
</div>
</template>
<script>
// 引入组件
import Category from './components/Category'
export default {
name:'App',
// 注册组件
components:{Category},
}
</script> - Category子组件(省略css样式)
<template>
<div class="Category">
<h3>{{title}}</h3>
<!-- 定义一个插槽(slot就是插槽的入口) -->
<!-- 不写的话你在App组件中写的结构体是即便是被解析了也不会显示 -->
<!-- :games="games" 将数据发送给父组件(App),指定作用域接收使用 -->
<slot :games="games">这是插槽的默认值,如果没有东西填入就会显示这段文字</slot>
</div>
</template>
<script>
export default {
name : 'Category',
// 接收父组件(App)传过来的数据(美食,电影,游戏等数据,以及标题)
props : ['title'],
data() {
return {
games : ['CSGO' , 'Apex' , 'Raionbow Six'],
}
},
}
</script>
结果展示:
这篇博客引用了作者为”╰☆阳光のboy“的文章
原文链接为:CSDN
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0许可协议。转载请注明来自 肥林の仓库