提示:该文章为笔者的个人笔记并不是权威,如有错误,谢谢指出。
插槽
Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自 Web Components 规范草案,将<slot>元素作为承载分发内容的出口。 让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式。
默认插槽
默认插槽只提供一个slot 标签,父组件提供数据默认插入到slot插槽中。
<template>
<div class="category">
<h3>{{title}}分类</h3>
// 将父组件Category中的img与video标签,在slot中展示
<slot></slot>
<ul v-for="(item,index) in listData" :key="index">
<li>{{item}}</li>
</ul>
</div>
</template>
<script>
export default {
name: 'Category',
props: ['listData', 'title']
}
</script>
<style>
.category {
background-color: skyblue;
width: 200px;
height: 300px;
}
h3 {
text-align: center;
background-color: orange;
}
</style>
<template>
<div class="container">
<Category title="美食">
<img src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
</Category>
<Category title="游戏" :listData="games"></Category>
<Category title="电影">
<video src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
controls autoplay></video>
</Category>
</div>
</template>
<script>
import Category from './components/Category'
export default {
data() {
return {
foods:['火锅','烧烤','小龙虾','牛排'],
games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
films:['《教父》','《拆弹专家》','《你好,李焕英》','《西红柿首富》']
}
},
name: 'App',
components: {Category}
}
</script>
<style scoped>
.container {
display: flex;
justify-content: space-around;
}
img,
video {
width: 100%;
}
</style>
具名插槽
具名插槽与默认插槽相似,具名插槽提供不同署名的slot表示,可以在指定标签中插入html结构,slot提供name属性,标明不同署名标签。
<template>
<div class="category">
<h3>{{title}}分类</h3>
// 提供两个插槽,分别名为center和footer
<slot name="center"></slot>
<slot name="footer"></slot>
</div>
</template>
<script>
export default {
name: 'Category',
props: ['listData', 'title']
}
</script>
<style>
.category {
background-color: skyblue;
width: 200px;
height: 300px;
}
h3 {
text-align: center;
background-color: orange;
}
</style>
<template>
<div class="container">
<Category title="美食">
<img slot="center" src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
<a slot="footer" href="http://www.baidu.com">更多美食</a>
</Category>
<Category title="游戏" :listData="games">
<ul slot="center">
<li v-for="(g,index) in games" :key="index">{{g}}</li>
</ul>
<div slot="footer">
<a href="http://www.baidu.com">单机游戏</a>
</div>
</Category>
<Category title="电影">
<video slot="center"
src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
controls autoplay></video>
<template v-solt:footer>
<div slot="footer">
<a href="http://www.baidu.com">经典</a>
</div>
<h4>欢迎</h4>
</template>
</Category>
</div>
</template>
<script>
import Category from './components/Category'
export default {
data() {
return {
foods:['火锅','烧烤','小龙虾','牛排'],
games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
films:['《教父》','《拆弹专家》','《你好,李焕英》', '《西红柿首富》']
}
},
name: 'App',
components: {Category}
}
</script>
<style scoped>
.container,
a {
display: flex;
justify-content: space-around;
}
img,
video {
width: 100%;
}
</style>
作用域插槽
目的是为了让插槽内容能够访问子组件中才有的数据。
<template>
<div class="category">
<h3>{{title}}分类</h3>
<slot :games="games"></slot>
</div>
</template>
<script>
export default {
name: 'Category',
props: ['title'],
data() {
return {
games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
}
},
}
</script>
<style>
.category {
background-color: skyblue;
width: 200px;
height: 300px;
}
h3 {
text-align: center;
background-color: orange;
}
</style>
<template>
<div class="container">
<Category title="游戏">
<template scope="game">
<ul v-for="(g,index) in game.games" :key="index">
<li>{{g}}</li>
</ul>
</template>
</Category>
<Category title="游戏">
<template scope="game">
<ol v-for="(g,index) in game.games" :key="index">
<li>{{g}}</li>
</ol>
</template>
</Category>
<Category title="游戏">
<template scope="game">
<h4 v-for="(g,index) in game.games" :key="index">{{g}}</h4>
</template>
</Category>
</div>
</template>
<script>
import Category from './components/Category'
export default {
data() {
return {
}
},
name: 'App',
components: {Category}
}
</script>
<style scoped>
.container,
a {
display: flex;
justify-content: space-around;
}
img,
video {
width: 100%;
}
</style>
slot 和 slot-scope以及被弃用,取而代之的是v-slot指令,v-slot也有缩写形式,例如v-slot:header可以被重写为#header。
<template>
<div class="container">
<Category title="游戏">
// 解构插槽
<template v-slot="{games}">
<ul v-for="(g,index) in games" :key="index">
<li>{{g}}</li>
</ul>
</template>
</Category>
<Category title="游戏">
// v-solt 指令
<template v-slot:default="game">
<ol v-for="(g,index) in game.games" :key="index">
<li>{{g}}</li>
</ol>
</template>
</Category>
<Category title="游戏">
<template v-slot:default="game">
<h4 v-for="(g,index) in game.games" :key="index">{{g}}</h4>
</template>
</Category>
</div>
</template>