插槽
(1) 什么是插槽
插槽:英文单词slot
抽取公共组件时,组件内部总会出现一些差异性内容;Vue
中提供了一种空间占位语法,称为插槽,如展示信息提示窗口:
官方文档:https://cn.vuejs.org/v2/guide/components-slots.html
(2) 匿名插槽
项目视图中,子组件中占有一个差异位置,可以通过匿名插槽实现占位
列表页面中,需要展示不同类型数据的新闻数据、通知数据、公告数据
① 定义插槽:
<template>
<div class="s-container">
<h3>功能组件</h3>
<div>
<!-- 插槽:匿名插槽 -->
<slot></slot>
</div>
<div>
公共底部内容
</div>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
.s-container{
width: 400px;
padding: 10px;
border-radius: 5px;
box-shadow: #333 0 0 2px;
}
</style>
② 给插槽中注入数据,编辑
<template>
<div class="list-container">
<h2>列表页面</h2>
<!-- 1、没有插入内容的子组件-->
<DataList/>
<!-- 2、新闻数据-->
<DataList>
<!-- 给匿名插槽添加内容 -->
<ul>
<li v-for="news in newsList" :key="news.id">{{ news.content}} </li>
</ul>
</DataList>
<!-- 3、通知内容 -->
<DataList>
<ol>
<li v-for="notice in noticeList" :key="notice.id">{{notice.content}}</li>
</ol>
</DataList>
<!-- 4、通知内容-->
<DataList>
<div v-for="advice in adviceList" :key="advice.id">{{advice.body}}</div>
</DataList>
</div>
</template>
<script>
import DataList from '../components/DataList.vue'
export default {
data() {
return {
newsList: [
{id: 2, content: "苹果系统升级"},
{id: 1, content: "全球互联网大会"}
],
noticeList: [
{id: 1, content: "周末大家一定要加强练习"}
],
adviceList: [
{id: 3, body: "完成周内的晨测"},
{id: 2, body: "梳理一周的学习内容"},
{id: 1, body: "完成项目任务"}
]
}
},
components: {
DataList
}
}
</script>
<style>
</style>
(3) 具名插槽
项目中定义弹出窗口,多个页面中都出现了弹窗,需要将弹窗抽取成一个功能组件;功能组件中不同的位置展示的内容不同,表示差异内容的位置不止一个!
① 定义包含具名插槽的公共组件
<template>
<div class="d-container">
<!-- 弹窗标题-->
<h3><slot name="title"></slot></h3>
<!-- 弹窗内容-->
<p><slot></slot></p>
<!-- 弹窗操作-->
<div><slot name="opera"></slot></div>
</div>
</template>
<script>
export default {
}
</script>
<style>
.d-container{
width: 300px;
height: 100px;
box-shadow: #000 0 0 2px;
}
</style>
② 添加具名插槽内容
<template>
<div class="list-container">
<!-- 具名插槽-->
<Dialog>
<template v-slot:title>
警告信息对话框
</template>
<template v-slot:opera>
<button>确认</button>
</template>
<p>
警告信息的提示内容
</p>
</Dialog>
<Dialog>
<template #title>
确认信息
</template>
<template #opera>
<button>编辑</button>
<button>确认</button>
</template>
<p>
确认信息的提示内容
</p>
</Dialog>
<Dialog>
<template slot-scope:title>
危险操作提示
</template>
<template slot-scope:opera>
<button>确认操作</button>
</template>
<p>
微信操作信息的提示内容
</p>
</Dialog>
</div>
</template>
<script>
import DataList from '../components/DataList.vue'
import Dialog from '../components/Dialog.vue'
export default {
data() {
return {...},
components: {
DataList,
Dialog
}
}
</script>
<style>
</style>
(4) 作用域插槽(重点)
插槽中可以实现父组件给子组件注入数据完成数据的渲染;一旦输入的数据包含和用户之间的交互操作,需要子组件通过插槽给父组件传递数据
① 编写作用域插槽
<template>
<div class="sc-container">
<ul>
<li v-for="news in newsList" :key="news.id">
<p>
<span>{{ news.id }}</span>
<span>{{ news.content }}</span>
<span>
<!-- 需要插槽给父组件传递正在操作的数据 -->
<!-- 通过插槽的属性进行传递:作用域插槽-->
<slot :row="news"></slot>
</span>
</p>
</li>
</ul>
</div>
</template>
<script>
export default {
props: ['newsList']
}
</script>
<style scoped>
.sc-container{
padding:20px;
box-shadow: #000 0 0 2px;
width: 400px;
}
</style>
② 添加接受作用域数据的插槽组件
<!-- 作用域插槽-->
<ScopeList :newsList="newsList">
<template v-slot="props">
<button @click="checkDetail(props)">查看详情</button>
</template>
</ScopeList>
<ScopeList :newsList="newsList">
<template v-slot="attr">
<!-- <template slot-scope="attr"> -->
<button @click="edit(attr)">编辑</button>
<button @click="del(attr)">删除</button>
</template>
</ScopeList>
(5) 小总结
插槽slot
主要区分三种
- 匿名插槽:
<slot></slot>
- 功能组件中,添加唯一一个占位位置,由父组件指定这个位置的内容
- 具名插槽:
<slot name="mySlot"></slot>
- 功能组件中,需要在多个位置添加不同的内容,通过具名插槽实现,父组件中指定插槽的名称填充数据
- 作用域插槽:
<slot :row="数据"></slot>
- 功能组件中,需要将插槽中的数据传递给父组件使用;通过插槽的自定义属性进行数据传输