Vue 插槽
文章目录
- [Vue 插槽](#Vue 插槽)
插槽的作用 :让组件内部的一些 结构 支持自定义。
例如:我们需要再页面中显示一个对话框,将其封装成一个组件。
当我们希望组件内容部分,不希望写死,就得用插槽来解决
插槽的分类:
- 默认插槽: 组件内定制一处结构
- 具名插槽:组件内定制多处结构
- 作用于插槽:是插槽的一个传参语法
01-插槽-默认插槽
默认插槽-基本语法
- 组件内需要定制的结构部分,使用占位
- 使用组件时,标签内部,传入结构替换slot。
基本使用
javascript
MyDialog组件
1.组件内需要定制的结构部分,使用<slot></slot>占位
<div class="dialog-content">
<!-- 1. 在需要定制的位置,使用slot占位 -->
<slot></slot>
</div>
App.vue组件
2.使用组件时,<MyDialog></MyDialog>标签内部,传入结构替换slot。
<div class="app">
<!-- 2. 在使用组件时,组件标签内填入内容 -->
<MyDialog>
<div>你确认要退出么</div>
</MyDialog>
<MyDialog>
<p>你确认要删除吗</p>
<p>你确认要删除吗</p>
<p>你确认要删除吗</p>
</MyDialog>
</div>
02-插槽-后备内容(默认值)
通过插槽完成了内容的定制,传什么显示什么,但是如果我们在组件使用的时候,不传,则是空白
那么能否给插槽设置 默认显示内容呢?
默认值设置方法
- **语法:**在标签内,放置内容,这里面的内容会被默认显示。
- 当组件使用时传给了内容则不会显示标签里面的默认内容
javascript
MyDialog组件
1.
<div class="dialog-content">
<!-- 往slot标签内部,编写内容(会被作为后备默认内容) -->
<slot>我是默认的插槽内容</slot>
</div>
App.vue组件
<div class="app">
//一个不传值,一个传值
<MyDialog></MyDialog>
<MyDialog>
我传递了内容哦!
</MyDialog>
</div>
说白了就是当不给组件传值的时候,就显示slot标签内部的内容。
03-插槽-具名插槽
当一个组件有多个结构,需要进行定制内容
此时的默认插槽是无法解决该问题
默认插槽:只能有一个定制位置
所以,得使用具名插槽来解决
具名插槽-语法
- 使用多个 slot 标签 ,并且使用 name 属性区分名字
- template配合 v-slot:名字 来分发对应标签
- 简写:v-slot:插槽名 → 可以简写为 #插槽名
javascript
MyDialog组件
1.
<div class="dialog-header">
<!-- 一但插槽起了名字,就是具名插槽,(只支持定向分发) -->
<slot name="head"></slot>
</div>
<!-- 内容 -->
<div class="dialog-content">
<slot name="content"></slot>
</div>
<!-- 底部 -->
<div class="dialog-footer">
<slot name="footer"></slot>
</div>
App.vue组件
2.切记用template包裹起来,根据插槽名分发内容
<MyDialog>
<!-- 需要通过template包裹,template配合 v-slot:名字 来分发对应标签 -->
<template v-slot:head>
<div>我是大标题</div>
</template>
<template v-slot:content>
<div>我是内容</div>
</template>
<!-- 简写#插槽名 -->
<template #footer>
<button>确认</button>
<button>取消</button>
</template>
</MyDialog>
04-插槽-作用域插槽
作用于插槽:定义slot插槽的同时,是可以传值的。给 插槽 上可以 绑定数据,将来 使用组件时可以使用。
使用场景:封装表格组件
- 父传子,动态渲染表格内容
- 利用默认插槽,定制操作列表
- 删除或查看都需要用到 当前项 的 id ,数组组件内部数据(通过作用域插槽 传值绑定,进而使用)
默认插槽-语法
- 给 slot 标签 ,以添加属性的方式传值
<slot :id="item.id" msg="测试"></slot>
-
所有添加的属性,都会被收集到一个对象中
{ id: 3 , msg: '测试'}
-
在 template中,通过
#插槽名="obj"
接收,默认插槽名为: default →#default="obj"
这里使用一个简单的表格删除和查询来练习插槽
代码示例
首先是我们呢的子组件代码
javascript
<template>
<table class="my-table">
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年纪</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in data" :key="item.id">
<td>{{ index + 1 }}</td>
<td>{{ item.name }}</td>
<td>{{ item.age }}</td>
<td>
<!-- 定义插槽的同时,可以传值哦(使用插槽作用域) -->
<!-- 1. 给slot标签,添加属性的方式传值 -->
<slot :row="item" msg="测试">默认插槽</slot>
<!-- 2. 将所有的属性添加到一个对象中 -->
<!--
{
row : {id: 2 ,name: "孙大明", age: 19},
msg: '测试文本'
}
-->
</td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
props: {
data: Array
}
}
</script>
App.vue父组件代码
javascript
<template>
<div>
<MyTable :data="list">
<!-- 3. 通过template #插槽名="变量名" 接收 -->
<template #default = "obj">
<button @click="del(obj.row.id)">删除</button>
</template>
</MyTable>
<MyTable :data="list2">
<!-- 这里是一样的:需要使用template包裹 -->
<template #default="{row}">
<button @click="look(row)">查看</button>
</template>
</MyTable>
</div>
</template>
<script>
import MyTable from './components/MyTable.vue'
export default {
data () {
return {
list: [
{ id: 1, name: '张小花', age: 18 },
{ id: 2, name: '孙大明', age: 19 },
{ id: 3, name: '刘德忠', age: 17 },
],
list2: [
{ id: 1, name: '赵小云', age: 18 },
{ id: 2, name: '刘蓓蓓', age: 19 },
{ id: 3, name: '姜肖泰', age: 17 },
]
}
},
methods: {
del (id) {
// 删除功能:使用filter过滤
this.list = this.list.filter( item => item.id !== id)
},
look (row) {
alert(`姓名:${row.name}; 年纪:${row.age}`)
}
},
components: {
MyTable
}
}
</script>
这里主要讲解了插槽的语法和基本的使用。