插槽是什么?
在 Vue 2 中,插槽(slot)是一种用于定义组件内部内容分发的机制。它允许你将组件中的一部分内容替换为用户自定义的内容,并在组件内部进行渲染。
通过在组件模板中使用
标签,你可以指定一个插槽的位置。这个位置可以被父组件中的任意内容所填充。父组件中的内容将被插入到插槽所在的位置,并最终与组件的其他部分一起进行渲染。
<template>
<div class="dialog">
<div class="dialog-header">
<h3>友情提示h3>
<span class="close">✖️span>
div>
<div class="dialog-content">
<slot>你确认要退出本系统么?slot>
div>
<div class="dialog-footer">
<button>取消button>
<button>确认button>
div>
div>
template>
<script>
export default {
data () {
return {
}
}
}
script>
<style scoped>
* {
margin: 0;
padding: 0;
}
.dialog {
width: 470px;
height: 230px;
padding: 0 25px;
background-color: #ffffff;
margin: 40px auto;
border-radius: 5px;
}
.dialog-header {
height: 70px;
line-height: 70px;
font-size: 20px;
border-bottom: 1px solid #ccc;
position: relative;
}
.dialog-header .close {
position: absolute;
right: 0px;
top: 0px;
cursor: pointer;
}
.dialog-content {
height: 80px;
font-size: 18px;
padding: 15px 0;
}
.dialog-footer {
display: flex;
justify-content: flex-end;
}
.dialog-footer button {
width: 65px;
height: 35px;
background-color: #ffffff;
border: 1px solid #e1e3e9;
cursor: pointer;
outline: none;
margin-left: 10px;
border-radius: 3px;
}
.dialog-footer button:last-child {
background-color: #007acc;
color: #fff;
}
style>
在父组件中引入组件,并且在组件标签中写入内容。如果不写将展示默认
标签里面的文字,默认内容,也叫做后备内容。
<template>
<div id="app">
<MyDialog>你好!欢迎使用vue2MyDialog>
div>
template>
<script>
// import MyBodys from './components/MyBodys.vue';
import MyDialog from './components/MyDialog.vue';
export default {
name: "App",
data() {
return {
};
},
components:{
MyDialog
}
};
script>
<style>
#app {
width: 100%;
height: 700px;
background-color: rgb(167, 167, 167);
overflow: hidden;
}
*{
margin: 0;
padding: 0;
}
style>
一个组件可以拥有多个插槽,每个插槽可以有不同的名称,以便在父组件中选择性地进行内容分发。父组件可以使用 和
标签的 name 属性来决定插槽的位置和名称。
插槽的使用可以使组件更具灵活性,让父组件能够向子组件传递不同的内容,并在组件内部进行渲染。这在构建可重用的组件和布局时非常有用。
比如其中 弹出框的 标题 ,内容,以及按钮都不一样,我们就可以使用具名插槽来更改代码,为slot标签取名(name属性)
为组件中的slot取名:
<template>
<div class="dialog">
<div class="dialog-header">
<h3 ><slot name="title">友情提示slot>h3>
<span class="close">✖️span>
div>
<div class="dialog-content">
<slot name="content">你确认要退出本系统么?slot>
div>
<div class="dialog-footer">
<slot name="button">
<button>取消button>
<button>确认button>
slot>
div>
div>
template>
<script>
export default {
data () {
return {
}
}
}
script>
<style scoped>
* {
margin: 0;
padding: 0;
}
.dialog {
width: 470px;
height: 230px;
padding: 0 25px;
background-color: #ffffff;
margin: 40px auto;
border-radius: 5px;
}
.dialog-header {
height: 70px;
line-height: 70px;
font-size: 20px;
border-bottom: 1px solid #ccc;
position: relative;
}
.dialog-header .close {
position: absolute;
right: 0px;
top: 0px;
cursor: pointer;
}
.dialog-content {
height: 80px;
font-size: 18px;
padding: 15px 0;
}
.dialog-footer {
display: flex;
justify-content: flex-end;
}
.dialog-footer button {
width: 65px;
height: 35px;
background-color: #ffffff;
border: 1px solid #e1e3e9;
cursor: pointer;
outline: none;
margin-left: 10px;
border-radius: 3px;
}
.dialog-footer button:last-child {
background-color: #007acc;
color: #fff;
}
style>
为父组件的组件标签添加template标签,配合子组件:
<template>
<div id="app">
<MyDialog>
<template v-slot:title>我是标题template>
<template v-slot:content>我是内容template>
<template #button>
<button>取消button>
<button>确认button>
template>
MyDialog>
div>
template>
<script>
// import MyBodys from './components/MyBodys.vue';
import MyDialog from './components/MyDialog.vue';
export default {
name: "App",
data() {
return {
};
},
components:{
MyDialog
}
};
script>
<style>
#app {
width: 100%;
height: 700px;
background-color: rgb(167, 167, 167);
overflow: hidden;
}
*{
margin: 0;
padding: 0;
}
style>
最后效果:
插槽分类:
作用域插槽: 是插槽的一个传参语法.
删除或查看都需要用到 当前项的 id,属于 组件内部的数据 通过 作用域插槽 传值绑定,进而使用
1.渲染子组件,并且在子组件slot标签中添加:all="item" :msg="item.id"
属性,用于作用域插槽 传值。
<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>
<slot :all="item" :msg="item.id">
<button>删除button>
slot>
td>
tr>
tbody>
table>
template>
<script>
export default {
props: {
data: Array,
},
}
script>
<style scoped>
.my-table {
width: 450px;
text-align: center;
border: 1px solid #ccc;
font-size: 24px;
margin: 30px auto;
}
.my-table thead {
background-color: #1f74ff;
color: #fff;
}
.my-table thead th {
font-weight: normal;
}
.my-table thead tr {
line-height: 40px;
}
.my-table th,
.my-table td {
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
}
.my-table td:last-child {
border-right: none;
}
.my-table tr:last-child td {
border-bottom: none;
}
.my-table button {
width: 65px;
height: 35px;
font-size: 18px;
border: 1px solid #ccc;
outline: none;
border-radius: 3px;
cursor: pointer;
background-color: #ffffff;
margin-left: 5px;
}
style>
2.在template中,通过 #插槽名="obj” 接收,默认插槽名为 default
<template>
<div id="app">
<MyTable :data="list" #default="obj">
<button @click="deletelist(obj)">删除button>
MyTable>
<MyTable :data="list2" #default="obj">
<button @click="chakanlist(obj)">查看button>
MyTable>
div>
template>
<script>
// import MyBodys from './components/MyBodys.vue';
import MyTable from './components/MyTable.vue';
export default {
name: "App",
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 },
]
};
},
components:{
MyTable
},
methods:{
chakanlist(obj){
console.log(obj.all)
console.log(obj.msg)
alert("姓名:"+obj.all.name+" 年龄:"+obj.all.age)
},
deletelist(obj){
this.list = this.list.filter(item => item.id != obj.all.id)
}
}
};
script>
<style>
#app {
width: 100%;
height: 700px;
background-color: rgb(255, 255, 255);
overflow: hidden;
}
*{
margin: 0;
padding: 0;
}
style>