即插槽,插槽定义在子组件内,是组件的一块HTML模板,可以在子组件内设置默认值,也可以在父组件内定义插槽内显示的内容
默认插槽,具名插槽和作用域插槽
举个例子:
<!-- child组件 -->
<template>
<section>
<!-- 具名插槽 -->
<slot name="header">
<header>这是子组件内定义header</header>
</slot>
<!-- 匿名插槽 -->
<slot></slot>
<!-- 具名插槽 -->
<slot name="footer">
<footer>这是子组件内定义footer</footer>
</slot>
</section>
</template>
<!-- 父组件内使用 -->
<template>
<div>
<child>
<div>父组件内定义内容</div>
<footer slot="footer">父组件内定义插槽内容</footer>
</child>
</div>
</template>
<slot name="header">
和<slot name="footer">
是具名插槽,在父组件使用时,在<child>
标签内定义任意标签,并添加属性slot = “name”
,则该标签就会覆盖组件内对用的插槽内容。<slot>
是匿名插槽,不设置name属性,<child>
标签内,不被具名插槽包裹的内容,会覆盖匿名插槽的内容。
<!-- child组件 -->
<ul>
<li v-for="todo in todos" :key="todo.id">
<slot :todo="todo">
<!-- 回退的内容 -->
{{ todo.text }}
</slot>
</li>
</ul>
<!-- 使用 -->
<child :todos="todos">
<!-- 将 `slotProps` 定义为插槽作用域的名字 -->
<template slot-scope="slotProps">
<span v-if="slotProps.todo.isComplete">✓</span>
{{ slotProps.todo.text }}
</template>
</child>
子组件内,定义slot,绑定todo
属性,在父组件内使用时,在child
内,通过slot-scope
接受一个对象参数,可以根据参数,定制每个代办项。slot-scope="{todo}"
可以结构获取参数。可是定义多个作用域插槽。
针对ElementUI框架Table组件的二次封装
<!-- 二次封装 z-table -->
<div>
<el-table :data="rows"
v-loading="loading"
v-bind="$attrs"
v-on="$listeners"
ref="table"
empty-text="没有满足条件的数据哦!">
<!-- 公共column等等。 -->
<el-table-column v-for="col in columns"
:key="col.colName"
:label="col.viewName"
:width="col.width"
:prop="col.colName"
show-overflow-tooltip>
<!-- 通过slot-scope获取el-table定义的row -->
<template slot-scope="{row}">
<!-- 将row和col属性,通过作用域插槽暴露给父组件 -->
<slot :col="col" :row="row">
{{row[col.colName]}}
</slot>
</template>
</el-table-column>
</el-table>
<!-- pagination等其他公共设置 -->
<div>
<!-- 使用 -->
<z-table :rows="rows" :columns="cols" :loading="loading" checked :page="pages" @changePage="pageChange">
<template slot-scope="{col,row}">
<div v-if="true">
<!-- todo -->
</div>
<div v-else>
{{row[col.colName]}}
</div>
</template>
</z-table>