一、插槽的概念
组件标签中的内容,是不会显示在页面中的,要想显示出来,就要使用插槽
js
<template>
<div class="child">
child组件
<slot />
</div>
</template>
当在子组件中写上<slot />
标签,书写在<Child></Child>
中的内容便会在这个位置展示出来
二、具名插槽和匿名插槽
Child.vue
js
<template>
<div class="child">
<header>
<slot name="header" />
</header>
<main>
<slot />
</main>
<footer>
<slot name="footer" />
</footer>
</div>
</template>
Parent.vue
js
<template>
<div class="parent">
parent组件
<Child>
<h1 slot="header">标题</h1>
<p>内容</p>
<p slot="footer">底部</p>
</Child>
</div>
</template>
slot标签的name属性就是具名插槽,否则就是匿名插槽,如果需要让某个内容显示在固定的位置上,可以考虑使用具名插槽
2.6.0+
版本,父组件中可以这样写:
js
<template v-slot:footer>
<p>底部</p>
</template>
但不能将v-slot:footer
直接定义在p标签上
还可以使用#
语法糖(v-slot:
可以简写成#
):
js
<template #footer>
<p>底部</p>
</template>
三、插槽作用域
1、插槽作用域的作用:子组件可以传值给父组件
2、匿名插槽作用域传值
Child.vue
js
<main>
<slot :params="{ name: '小明', age: 18 }" />
</main>
Parent.vue
老的写法
js
<template slot-scope="scope">
<p>
内容
{{ scope.params.name }}--{{ scope.params.age }}
</p>
</template>
2.6.0+ slot-scope
可以写成v-slot
js
<template v-slot="scope">
<p>
内容
{{ scope.params.name }}--{{ scope.params.age }}
</p>
</template>
scope是自定义的变量名,可以用其他名字,也可以使用解构赋值
js
<template v-slot="{ params }">
<p>
内容
{{ params.name }}--{{ params.age }}
</p>
</template>
3、具名插槽作用域传值
Child.vue
js
<header>
<slot name="header" :params="{ name: '小明', age: 18 }" />
</header>
Parent.vue
老的写法
js
<template slot="header" slot-scope="scope">
<h1>标题</h1>
{{ scope.params.name }}--{{ scope.params.age }}
</template>
2.6.0+
js
<template v-slot:header="{ params }">
<h1>标题</h1>
{{ params.name }}--{{ params.age }}
</template>
使用#简写:
js
<template #header="{ params }">
<h1>标题</h1>
{{ params.name }}--{{ params.age }}
</template>
四、解读el-table
中使用的插槽
这里使用slot-scope="scope"
,说明el-table-column
组件中通过slot
标签传递了一些值供父组件使用
咱们来模拟一下:
效果:
Parent.vue
js
<template>
<div class="parent">
parent组件
<Child :tableData="tableData">
<template v-slot="scope">
<el-button @click="handleClick(scope.row)">查看</el-button>
<el-button>编辑</el-button>
</template>
</Child>
</div>
</template>
<script>
import Child from '../Child'
export default {
components: { Child },
data() {
return {
tableData: [
{ id: 1, name: '小明' },
{ id: 2, name: '小华' },
{ id: 3, name: '小王' }
]
}
},
methods: {
handleClick(row) {
console.log({ ...row })
}
}
}
</script>
<style lang="less" scoped>
.parent {
width: 200px;
border: 1px solid deeppink;
color: deeppink;
padding: 10px;
}
</style>
Child.vue
js
<template>
<div class="child">
<div v-for="row of tableData" :key="row.id">
<slot :row="row" />
</div>
</div>
</template>
<script>
export default {
props: ['tableData']
}
</script>
<style lang="less" scoped>
.child {
width: 150px;
border: 1px solid deepskyblue;
color: deepskyblue;
}
</style>