插槽
默认插槽
- 在App组件内使用双标签引用子组件
- 在子组件内写入slot(插槽)标签等待接收传递内容
- 在双标签内传入需要插槽接收的内容
App组件
<template>
<div class="container">
<Category title="美食">
<img src="https://img2.baidu.com/it/u=2152778983,3447357881&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500">
</Category>
<Category title="游戏">
<ul>
<li v-for="(item,index) in games" :key="index">
{{ item }}
</li>
</ul>
</Category>
<Category title="电影">
<video controls src="http://vjs.zencdn.net/v/oceans.mp4"></video>
</Category>
</div>
</template>
<script>
import Category from "@/components/Category.vue";
export default {
name: 'App',
components: {
Category
},
data(){
return{
foods:['烧烤','火锅','小龙虾','牛排'],
games:['扫雷','俄罗斯方块','推箱子','超级玛丽'],
films:['《熊出没》','《大鱼》','《哈利波特》','《教父》'],
}
}
}
</script>
Category组件
<script>
import {defineComponent} from 'vue'
export default defineComponent({
name: "Category",
props: ['title']
})
</script>
<template>
<div class="category">
<h3>{{ title }}分类</h3>
<!-- 定义一个插槽,若在插槽中配置默认值,当用户传值展示用户内容,用户不传值展示默认值 -->
<slot></slot>
</div>
</template>
具名插槽
- 同时使用多个slot插槽时,为每一个插槽添加一个name属性进行命名
- 在相应的插入内容的元素中添加一个slot属性与name命名对应
- 注: 当元素是template标签时,可不用slot属性使用v-slot属性
App组件
<template>
<div class="container">
<Category title="美食">
<img slot="center"
src="https://img2.baidu.com/it/u=2152778983,3447357881&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500"
alt="">
<a slot="footer" href="https://www.baidu.com">更多美食</a>
</Category>
<Category title="游戏">
<ul slot="center">
<li v-for="(item,index) in games" :key="index">
{{ item }}
</li>
</ul>
<div slot="footer" class="foot">
<a href="https://www.baidu.com">单机游戏</a>
<a href="https://www.baidu.com">网络游戏</a>
</div>
</Category>
<Category title="电影">
<video slot="center" controls src="http://vjs.zencdn.net/v/oceans.mp4"></video>
//用法1
<template slot="footer">
<div class="foot">
<a href="https://www.baidu.com">经典</a>
<a href="https://www.baidu.com">热门</a>
<a href="https://www.baidu.com">推荐</a>
</div>
<h4>欢迎前来观影</h4>
</template>
//用法2
<template v-slot:footer>
<!--v-slot:footer只能用在template标签上-->
<div class="foot">
<a href="https://www.baidu.com">经典</a>
<a href="https://www.baidu.com">热门</a>
<a href="https://www.baidu.com">推荐</a>
</div>
<h4>欢迎前来观影</h4>
</template>
</Category>
</div>
</template>
Category组件
<template>
<div class="category">
<h3>{{ title }}分类</h3>
<slot name="center"></slot>
<slot name="footer"></slot>
</div>
</template>
作用域插槽
理解:
- 数据存放在定义插槽的组件自身中
- 结构由插槽的使用者决定
- 作用域插槽可以有名字
- 使用双标签引用子组件
- 子组件的结构由template标签包裹,标签添加scope属性或slot-scope属性,属性值由子组件动态传入
- 子组件中存放data数据
- 子组件定义插槽时动态绑定自定义名称的数据对象
App组件
<template>
<div class="container">
<Category title="游戏">
<template scope="game">
<ul>
<li v-for="(item,index) in game.games" :key="index">
{{ item }}
</li>
</ul>
</template>
</Category>
<Category title="游戏">
<template slot-scope="{games}">
<ol>
<li v-for="(item,index) in games" :key="index">
{{ item }}
</li>
</ol>
</template>
</Category>
<Category title="游戏">
<template scope="{games}">
<h4 v-for="(item,index) in games" :key="index">
{{ item }}
</h4>
</template>
</Category>
</div>
</template>
Category组件
<script>
import {defineComponent} from 'vue'
export default defineComponent({
name: "Category",
props: ['title'],
data() {
return {
games: ['扫雷', '俄罗斯方块', '推箱子', '超级玛丽'],
}
}
})
</script>
<template>
<div class="category">
<h3>{{ title }}分类</h3>
<slot :games="games"></slot>
</div>
</template>
总结
- 作用: 让父组件可向子组件的指定位置插入HTML结构,是组件间一中通信方式
- 分类: 默认插槽、具名插槽、作用域插槽