100行代码~table表格封装(源码)🔥
基于element组件
自定义Table组件,用于整合页码组件el-pagination;已优化colums的写法
目的
解决table和分页组件每次都要分开写的问题
- 分页组件合并封装
- 页码能方便重置
优化模版colum过多
- 使用数组遍历渲染
- 插槽参考switch
组件缩略图

使用
<!-- 表格 -->
<sp-table
class="table"
:data="tableData"
:columns="columns"
:paginationSeting="paginationSeting"
style="width: 100%"
height="550"
stripe
@done="val => (tableInstance = val)"
>
<template slot="mobile" slot-scope="scope">
<div>手机号:{{ scope.row.mobile }}</div>
</template>
<template slot="operation" slot-scope="scope">
<div>{{ scope.row.id }}</div>
</template>
<template slot="operationHeader" slot-scope="scope">
<div>{{ scope.column.label }}(功能区域)</div>
</template>
</sp-table>
Props
table的属性方法都没有改变与官网保持一致
| 参数 | 类型 | 默认值 | 可选项 | 备注 |
|---|
| paginationSeting | Object | 默认 | -- | 与el-pagination组件属性一致,方法当做属性传递 |
| columns | Object | 默认 | -- | 请看下面的结构 |
| done | Function | 默认 | -- | 初始化完成函数 |
columns的属性与官网Table-column Attributes保持一致,一下是增量属性
| 参数 | 类型 | 默认值 | 可选项 | 备注 |
|---|
| scopedSlot | Srting | -- | -- | 是否使用自定义插槽来渲染 |
| isSlotHeader | Boolean | -- | -- | 是否自定义渲染表头cloum,表头插槽为${scopedSlot}Header |
Methods(与el-table一致)
Slot (与el-table一致)
代码
<template>
<div>
<el-table v-bind="$attrs" v-on="$listeners" ref="refTable">
<template v-for="(col, index) in columns">
<el-table-column v-if="!col.scopedSlot" v-bind="col" :key="index">
</el-table-column>
<el-table-column v-else :key="index" v-bind="col">
<template slot="header" slot-scope="scope">
<slot
v-if="col.isSlotHeader"
:name="`${col.scopedSlot}Header`"
v-bind="{ col: col, column: scope.column }"
>
</slot>
<div v-else>{{ scope.column.label }}</div>
</template>
<template slot-scope="scope">
<slot :name="col.scopedSlot" v-bind="{ col: col, row: scope.row }">
</slot>
</template>
</el-table-column>
</template>
</el-table>
<el-pagination
v-bind="paginationOptions"
class="pagination"
:class="paginationSeting.class"
:style="paginationSeting.style"
:total="paginationSeting.pageTotal"
:current-page="paginationOptions.currentPage"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
@prev-click="paginationOptions.prevClick"
@next-click="paginationOptions.nextClick"
>
</el-pagination>
</div>
</template>
<script>
export default {
name: 'spTable',
props: {
columns: {
type: Array,
default: () => []
},
paginationSeting: {
type: Object,
default: () => {}
}
},
data() {
return {
paginationOptions: {
currentPage: 1,
pageSize: 10,
pageTotal: 0,
background: true,
pageSizes: [10, 30, 50, 100],
layout: 'total, prev, pager, next,sizes, jumper',
prevClick: () => {},
nextClick: () => {}
}
}
},
created() {
this.paginationOptions = {
...this.paginationOptions,
...this.paginationSeting
}
},
mounted() {
if (this.$refs.refTable) this.$emit('done', this.$refs.refTable)
},
methods: {
handleSizeChange(val) {
this.pageSize = val
this.paginationOptions.sizeChange(val)
},
handleCurrentChange(val) {
this.currentPage = val
this.paginationOptions.currentChange(val)
}
}
}
</script>
<style lang="scss" scoped>
.pagination {
position: relative;
margin-top: 15px;
display: flex;
justify-content: end;
}
::v-deep {
.el-pagination__total {
position: absolute !important;
left: 0 !important;
}
}
</style>