1.在components文件下新建一个table文件,创建customTable.vue文件
customTable.vue代码如下:
<template>
<div class="table-box" :style="{ width: width }">
<div class="row justify-between">
<slot name="top"></slot>
</div>
<el-table :border="isBorder" :data="data" @selection-change="selection">
<el-table-column
v-if="selectable"
type="selection"
width="55"
:resizable="false"
></el-table-column>
<el-table-column
v-for="item in columns"
:key="item.prop"
v-bind="item"
show-overflow-tooltip
:formatter="formatter"
:resizable="false"
>
<template v-if="item.__slotName" v-slot="scope">
<slot :name="item.__slotName" :data="scope"></slot>
</template>
</el-table-column>
</el-table>
<div class="row justify-end">
<slot name="pagination"></slot>
</div>
</div>
</template>
<script>
export default {
name: "customTable",
props: {
// 表头信息
columns: {
type: Array,
default: () => []
},
// 表格数据
data: {
type: Array,
default: () => []
},
// 是否可选
selectable: {
type: Boolean,
default: false
},
isBorder: {
type: Boolean,
default: true
},
width: {
type: String
}
},
data() {
return {};
},
created() {},
methods: {
selection(data) {
this.$emit("selectionChange", data);
},
formatter(r, c, v) {
switch (v) {
case true: {
return "是";
}
case false: {
return "否";
}
default: {
return v || "-";
}
}
}
}
};
</script>
<style lang="less" scoped></style>
自定义插槽解释:
<template v-if="item.__slotName" v-slot="scope">
<slot :name="item.__slotName" :data="scope"></slot>
</template>
<template v-if="item.__slotName" v-slot="scope">
这部分代码是用来判断当前列是否有一个名为 __slotName
的属性,如果有的话,则使用插槽 (<slot>
) 来自定义列的内容。
具体来说,在循环遍历 columns
数组中的每个元素时,v-if="item.__slotName"
这个条件判断会检查当前列对象 item
是否有 __slotName
这个属性。
如果 item
对象有 __slotName
属性,表明需要自定义该列的内容,那么内部的 <template>
就会被执行,通过 v-slot="scope"
来创建一个作用域插槽,并将该插槽命名为 item.__slotName
。同时,<slot>
组件会被放置在插槽标记的位置,通过 :name="item.__slotName"
将其赋予相同的插槽名称,并传递 scope
对象作为插槽的数据。
这样,当表格渲染时,如果列对象中有 __slotName
属性,就会使用自定义插槽的内容来渲染该列,否则会使用默认的列渲染。
2.在需要使用组件的地方引入封装好的表格组件:
<custom-table
:columns="columns"
:data="list"
:selectable="false"
:isBorder="false"
>
//如果在表头需要有按钮,比如新建,批量删除等按钮时,可使用插槽
<template slot="top">
<div class="top-btn flex justify-between">
<div>
<el-button
type="primary"
icon="el-icon-plus"
@click="handleOpen('新建')"
>新建</el-button>
</div>
<el-button icon="el-icon-download">下载</el-button>
</div>
</template>
//如果需要给每列的数据单独加操作
<template slot="spotNum" slot-scope="scope">
<span>{{ scope.data.row.spotNum }}</span>
<span @click="handleOpen('编辑', scope.data.row)"
><i class="el-icon-edit"></i
></span>
</template>
//行末的详情删除操作
<template slot="option" slot-scope="scope"> <!--slot-scope的作用就是获取当前所在元素的数据-->
<el-button type="text" @click="toEdit(scope.data.row)">详情</el-button>
<el-button type="text">删除</el-button>
</template>
//加入分页组件
<template slot="pagination">
<pagination
v-show="total > 0"
:total="total"
:page.sync="listQuery.page"
:limit.sync="listQuery.size"
@pagination="getList"
/>
</template>
</custom-table>
每列的数据单独加操作的案例图:
定义在data中的数据:
data(){
return{
total: 0,
list: [{}],
listQuery: {
page: 1,
size: 10,
search: {}
},
columns: [
{
label: "编号",
prop: "spotNum",
width: 80,
__slotName: "spotNum"
},
{
label: "时间",
prop: "Time"
},
{
label: "完成情况",
prop: "completionStatus"
},
{
label: "操作",
prop: "option",
fixed: "right",
width: 120,
__slotName: "option"
}
],
}
}
data中的数据大家根据实际需求进行写就行了,然后再methods中去写每一个按钮需要的方法。
关于分页组件具体的封装在这儿了,大家自取!