前言:仔细看懂本篇博客,玩转element table 不成问题 ,个人理解所谓封装,就是把经常都要公用的东西,拿出来,可以多次复用。公用方法,公用页面都可以封装。
其实封装也并不是有多难,思路也很简单,就是用JS来控制页面。页面动态性越强,组件越灵活,适用范围越广。
就vue+element的组件封装而言,先把所有功能在子页面实现。然后把js里面的动态值,拿到父组件里面去传过来,就完成了,其中技术也就掌握父子组件传值而已。
该组件封装适应于绝大多数table列表,可以自定义列
废话不多说看下例子
先上子组件代码
<template>
<div class="table-box">
<el-table
ref="tableData"
v-loading="loading"
:row-key="rowKey"
:style="{ width: '100%', fontSize: fontSize + 'px' }"
:show-header="showHeader"
:data="tableData"
:height="tableHeight"
:summary-method="getSummaries"
:show-summary="showSummary"
:cell-style="cellStyle"
:cell-class-name="tableCellClassName"
:span-method="arraySpanMethod"
:border="border"
size="default"
:highlight-current-row="highlightCurrentRow"
v-bind="tableInfo"
:stripe="isStripe"
v-on="events"
>
<slot name="expand" />
<!-- 多选 -->
<el-table-column
v-if="needSelect"
:selectable="selectable"
type="selection"
width="55"
:reserve-selection="isReserve"
/>
<el-table-column v-if="hasIndex" label="序号" width="50" type="index" />
<template v-for="(item, index) in tableColumn">
<!-- 此列需要自定义 notTooltip 超出行是否隐藏 -->
<el-table-column
v-if="item.isSlot"
:key="'%' + index"
:show-overflow-tooltip="!item.notTooltip"
v-bind="item"
v-on="events"
>
<template slot-scope="{ row, $index }">
<ex-slot
v-if="item.render"
:render="item.render"
:row="row"
:index="$index"
:column="item"
:class="item.prop"
:default-value="item.defaultValue"
/>
<slot v-else :name="item.prop" :row="row" />
</template>
</el-table-column>
<!-- 正常列 -->
<el-table-column
v-else
:key="'%' + index"
show-overflow-tooltip
v-bind="item"
v-on="events"
/>
</template>
<el-table-column
v-if="hasOperation"
label="操作"
:min-width="operationWidth"
:fixed="fixed"
align="center"
>
<!-- <template v-if="!btnButton || btnButton.length === 0" slot-scope="scope">
<slot name="operation" :row="scope.row" :index="scope.$index" />
</template> -->
<template v-if="btnButton.length" slot-scope="{ row, column, $index }">
<el-button
v-for="(value, i) in btnButton"
:key="'$' + i"
:style="{ fontSize: fontSize + 'px' }"
size="small"
:type="value.type"
:icon="value.icon"
:class="value.class"
:disabled="value.disabled && value.disabled(row, column, $index)"
@click.stop="value.callback(row, column, $index)"
>
{{ value.text }}
</el-button>
</template>
</el-table-column>
<!-- 只针对团队会诊页面 吧v-else关闭 -->
</el-table>
<!-- 分页 -->
<div
v-if="isNeedPagination"
style="display: flex; justify-content: flex-end; align-item: centerl; padding-top: 15px"
>
<el-pagination
ref="pagination"
:page-sizes="pageSizes"
:page-size.sync="computedPageSize"
:hide-on-single-page="isSinglePageHide"
layout="total, sizes, prev, pager, next, jumper"
:current-page.sync="computedCurrentPage"
:total="total"
:small="small"
:pager-count="pagerCount"
@current-change="currentChange"
@size-change="sizeChange"
/>
</div>
</div>
</template>
<script>
import store from '@/store'
import { mapState } from 'vuex'
// 自定义组件的内容
const exSlot = {
functional: true,
props: {
row: Object,
render: Function,
index: Number,
column: {
type: Object,
default: null
},
defaultValue: [Number, String]
},
render: (h, ctx) => {
const params = {
row: ctx.props.row,
index: ctx.props.index
}
const defaultValue = ctx.props.defaultValue
params.column = ctx.props.column || {}
return h(
'div',
{
class: [
params.column.prop || '',
params.column.class || params.column.className || ''
].join('')
},
[ctx.props.render(h, params) || defaultValue]
)
}
}
export default {
name: 'PublicTable',
components: {
'ex-slot': exSlot
},
props: {
// key(唯一key值,和reserve-selection搭配使用)
rowKey: {
type: [Object, Function],
default: () => ({})
},
// 多选框是否记住上一页数据(必须与row-key唯一值搭配使用)
isReserve: {
type: Boolean,
default: false
},
// 单元格的 style 的回调方法
cellStyle: {
type: [Object, Function],
default: () => ({})
},
small: {
type: Boolean,
default: false
},
pagerCount: {
type: Number,
default: 7
},
// 是否显示表头
showHeader: {
type: Boolean,
default: true
},
// 是否显示合计
showSummary: {
type: Boolean,
default: false
},
// 是否要高亮当前行
highlightCurrentRow: {
type: Boolean,
default: true
},
// 自定义的合计计算方法
getSummaries: {
type: Function,
default: () => {}
},
// 获取表格行列索引值
tableCellClassName: {
type: Function,
default: () => {}
},
// 合并行或列
arraySpanMethod: {
type: Function,
default: () => {}
},
// 是否需要多选
needSelect: {
type: Boolean,
default: false
},
// 是否select需要特殊判断
selectable: {
type: Function,
default: () => {
return true
}
},
// 是否需要序号
hasIndex: {
type: Boolean,
default: false
},
// 默认是否选中第一列
isSetCurrentRow: {
type: Boolean,
default: false
},
// 是否需要分页
isNeedPagination: {
type: Boolean,
default: false
},
// 是否单页隐藏,默认为true
isSinglePageHide: {
type: Boolean,
default: false
},
// 当前页页码,支持.sync修饰符
currentPage: {
type: Number,
default: 1
},
// 每页数据条数, 支持.sync修饰符默认为每页10条
pageSize: {
type: Number,
default: 20
},
// 数据总条数
total: {
type: Number,
default: 0
},
// 每页多少数据
pageSizes: {
type: Array,
required: false,
default: () => [20, 40, 80, 100]
},
tableInfo: {
type: Object,
default: () => {}
},
// 获取数据时是否需要加载loading
loading: {
type: Boolean,
default: false
},
tableData: {
type: Array,
default: () => []
},
// 表格展示数据
tableColumn: {
type: Array,
default: () => []
},
// 是否需要操作列
hasOperation: {
type: Boolean,
default: true
},
// 是否需要边框
border: {
type: Boolean,
default: false
},
// 操作列
btnButton: {
type: Array,
default: () => []
},
// 操作列宽度
operationWidth: {
type: String,
default: '60px'
},
// 操作
fixed: {
type: [Boolean, String],
default: false
},
// 表格方法
events: {
type: Object,
default: () => {}
},
// 是否为斑马纹 table
isStripe: {
type: Boolean,
default: false
}
},
data() {
return {
fontSize: sessionStorage.getItem('fontSize') || ''
}
},
// data() {
// return {
// // eslint-disable-next-line vue/no-dupe-keys
// tableData: []
// }
// },
computed: {
computedCurrentPage: {
get() {
return this.currentPage
},
set(val) {
this.$emit('update:currentPage', val)
}
},
computedPageSize: {
get() {
return this.pageSize
},
set(val) {
this.$emit('update:pageSize', val)
}
},
tableHeight() {
console.log('height', !this.isNeedPagination ? '100%' : 'calc(100% - 47px)')
return !this.isNeedPagination ? '100%' : 'calc(100% - 47px)'
},
...mapState({
diagnosisSize: state => state.app.diagnosisSize
})
},
watch: {
'$parent.activeName'() {
this.$nextTick(() => {
this.$refs.tableData.doLayout()
})
},
diagnosisSize: {
handler(newValue) {
this.fontSize = newValue
}
}
},
mounted() {
if (this.isSetCurrentRow) {
setTimeout(() => {
this.$refs.tableData.setCurrentRow(this.tableData[0])
}, 500)
}
},
methods: {
// 页面切换事件 通过 @currentChange 绑定
currentChange(val) {
this.$emit('currentChange', val)
},
// 每页条数切换事件,通过@sizeChange 绑定
sizeChange(val) {
this.$emit('sizeChange', val)
},
getTableRef() {
return this.$refs.tableData
}
}
}
</script>
<style lang="scss" scoped>
.table-box {
flex: 1;
overflow: hidden;
width: 100%;
height: 100%;
}
::v-deep .el-table {
border: 1px solid #dfe6ec;
}
::v-deep .el-table th {
padding: 0;
height: 40px;
background: #f2f4fa;
box-shadow: 0px 1px 0px 0px #ebedf0;
// color: #191f25;
color: #000;
font-weight: 400;
}
::v-deep .el-table td {
padding: 0;
height: 40px;
}
::v-deep .el-table {
width: 100%;
.el-table__header-wrapper table,
.el-table__body-wrapper table {
// width: 100% !important;
}
.el-table__body,
.el-table__footer,
.el-table__header {
// table-layout: auto;
}
.maxMinBtn {
padding: 0 5px;
}
}
::v-deep .el-table--striped .el-table__body tr.el-table__row--striped td.el-table__cell {
background-color: #e6f3e2;
}
::v-deep .el-table__body tr.current-row {
.flex_div {
background: rgba(21, 91, 212, 0.3) !important;
}
td {
background: rgba(21, 91, 212, 0.3) !important;
}
td {
background: rgba(21, 91, 212, 0.2) !important;
}
}
</style>
再上父组件代码
<template>
<div class="tableBox">
<PublicTable
ref="zhenDuanWHTable"
class="table"
:loading="loading"
:current-page="searchParams.pageNum"
:total="total"
:page-size="searchParams.pageSize"
:table-data="tableData"
:table-info="tableInfo"
:table-column="columns"
:btn-button="operations"
:events="events"
operation-width="150px"
@sizeChange="handleSizeChange"
@currentChange="handleCurrentChange"
/>
</div>
</template>
<script>
import tableInfo from './mixins/tableInfo.js'
import PublicTable from '@/components/PublicTable/index.vue'
export default {
components: {
PublicTable
},
mixins: [tableInfo],
data() {
return {}
},
methods: {}
}
</script>
<style lang="scss" scoped>
.tableBox {
display: flex;
flex-direction: column;
width: 100%;
height: 600px;
.table {
height: calc(100% - 48px);
}
}
</style>
再上mixins/tableInfo.js代码
import mockData from './mockData'
export default {
data() {
return {
// 获取列表前是否loading加载
loading: false,
// 搜索查询的参数
searchParams: {
pageNum: 1,
pageSize: 10
},
// table数据源
tableData: mockData,
// 表格项绑定的属性
columns: [
{
prop: 'title',
label: '审核描述',
minWidth: '100px',
align: 'center',
formatter: row => (row.title ? row.title : '暂无标题')
},
{
prop: 'statusDesc',
minWidth: '100px',
align: 'center',
label: '审核状态'
},
{
prop: 'createBy',
minWidth: '100px',
align: 'center',
label: '申请人'
},
{
sortable: 'custom',
prop: 'createdTime',
minWidth: '100px',
align: 'center',
label: '申请时间'
},
{
prop: 'auditBy',
minWidth: '100px',
align: 'center',
label: '审核人'
},
{
minWidth: '100px',
align: 'center',
prop: 'auditTime',
label: '审核时间'
},
{
minWidth: '100px',
align: 'center',
prop: 'A',
label: '审核时间'
},
{
minWidth: '100px',
align: 'center',
prop: 'B',
label: '审核时间'
},
{
minWidth: '100px',
align: 'center',
prop: 'C',
label: '审核时间'
},
{
minWidth: '100px',
align: 'center',
prop: 'D',
label: '审核时间'
},
{
minWidth: '100px',
align: 'center',
prop: 'E',
label: '审核时间'
},
{
minWidth: '100px',
align: 'center',
prop: 'E',
label: '审核时间'
},
{
minWidth: '100px',
align: 'center',
prop: 'E',
label: '审核时间'
},
{
minWidth: '100px',
align: 'center',
prop: 'E',
label: '审核时间'
},
{
minWidth: '100px',
align: 'center',
prop: 'E',
label: '审核时间'
},
{
minWidth: '100px',
align: 'center',
prop: 'E',
label: '审核时间'
},
{
minWidth: '100px',
align: 'center',
prop: 'E',
label: '审核时间'
},
{
minWidth: '100px',
align: 'center',
prop: 'E',
label: '审核时间'
},
{
minWidth: '100px',
align: 'center',
prop: 'E',
label: '审核时间'
},
{
minWidth: '100px',
align: 'center',
prop: 'E',
label: '审核时间'
},
{
minWidth: '100px',
align: 'center',
prop: 'E',
label: '审核时间'
},
{
minWidth: '100px',
align: 'center',
prop: 'E',
label: '审核时间'
}
],
// 表格绑定的属性
tableInfo: {
stripe: true,
'highlight-current-row': true // 选中行高亮
},
events: {
'row-dblclick': row => {
//双击表格项触发的函数
console.log(row)
},
'row-click': row => {
// 单机表格项触发的函数
console.log('row', row)
}
},
// 操作列
operations: [
{
text: '编辑',
isShow: row => true, // 是否展示
isDisable: row => true, // 是否禁用
type: 'text',
class: 'el-text-color',
callback: row => {
this.handleAddOrEdit('edit', row)
}
}
],
total: 0
}
},
mounted() {},
methods: {
// 每也条数改变
handleSizeChange(pageSize) {
this.searchParams.pageSize = pageSize
},
// 改变页数
handleCurrentChange(pageNum) {
this.searchParams.pageNum = pageNum
},
handleAddOrEdit(type, row) {
if (type === 'edit') {
this.visible = true
this.infoData = row
}
}
}
}
假数据mockData(不用管)
export default [
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
},
{
title: 'A',
statusDesc: 1,
createBy: '甲',
createdTime: '2023-01-01 23:59:59',
auditBy: '乙',
auditTime: '2023-01-02 23:59:59'
}
]
最后附上效果图