element组件库中的table使用每次都要重新写每一列的配置,不够灵活,如下:
html
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="date" label="日期" width="180"> </el-table-column>
<el-table-column prop="name" label="姓名" width="180"> </el-table-column>
<el-table-column prop="address" label="地址"> </el-table-column>
</el-table>
想着就封装下,改成配置型的,属性兼容原element的el-table里的属性,也方便其他同事使用,如下:
html:
ini
<div class="table-comp">
<el-table class="table-comp-table" v-loading="loading" :key="configKey"
:data="data" :border="config && config.isnborder ? false : true" v-bind="{...config}"
@selection-change="handleSelectionChange"
@sort-change="handleSortChange"
@row-click="clickRow"
:header-cell-class-name="cellClassName"
:cell-class-name="cellClassName"
style="width: 100%">
<template v-for="colItem in columnConfig">
<el-table-column v-if="colItem.dataCode == 'index'" :key="colItem.dataCode"
type="index" v-bind="{...colItem}"
:align="colItem.align || 'center'"
:index="(i) => i + 1">
</el-table-column>
<el-table-column v-else-if="colItem.dataCode == 'selection'" :key="colItem.dataCode"
type="selection" v-bind="{...colItem}"
:align="colItem.align || 'center'"
:width="colItem.width || 55">
</el-table-column>
<el-table-column v-else :key="colItem.dataCode"
v-bind="{...colItem}" :prop="colItem.dataCode"
:header-align="colItem['header-align'] || 'center'"
:align="colItem.align || 'center'"
>
<template slot-scope="scope">
<slot :name="colItem.dataCode" v-bind="{row: scope.row, rowIndex: scope.$index }">
<p v-if="colItem.dataCode != 'act'" :class="{'tool-tip-cell-box': colItem['show-overflow-tooltip']}">{{scope.row[colItem.dataCode]}}</p>
</slot>
</template>
</el-table-column>
</template>
</el-table>
</div>
js:
javascript
props: {
columnConfig: {
type: Array,
default: () => []
},
data: {
type: Array,
default: () => []
},
config: {
type: Object,
default: () => {
return {
size: 'mini',
'tooltip-effect': 'dark',
'highlight-current-row': true,
stripe: true,
'header-cell-style': {background:'#F5F7FA', color:'#333'},
}
}
},
loading: {
type: Boolean,
default: false
}
},
methods: {
cellClassName({row, column, rowIndex, columnIndex}) {
return column.property + '-cell-box';
},
handleSelectionChange(e) {
this.$emit('selectionChange', e);
},
handleSortChange(e) {
this.$emit('sortChange', e);
},
clickRow(row, column, event) {
this.$emit('clickRow', row);
}
}
css
css
.table-comp {
.tool-tip-cell-box {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.table-comp-table td {
padding: 0;
.cell {
padding: 0 !important;
>div, >p {
// display: inline-block;
padding: 10px;
// width: calc(100% - 20px);
}
.tool-tip-cell-box {
display: inline;
}
.el-table__expand-icon {
padding: 0;
margin-right: -10px;
}
.el-table__placeholder {
width: 0;
}
}
}
.table-comp-table td.is-leaf {
padding: 6px 10px;
}
.act-td-box {
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
align-content: flex-start;
column-gap: 1%;
&::before, &::after {
content: '';
display: block;
}
.el-button {
margin: 1px 0;
}
}
}
组件说明:
arduino
props:
config: // el-table 配置 如
{
size: 'mini',
'tooltip-effect': 'dark',
'show-summary': true,
'summary-method': this.getSummaries
}
columnConfig: // column配置:
[
{ dataCode: 'index', align: 'center' }, // 序列号 可无
{ dataCode: 'selection', align: 'center' }, // 选择项 可无 搭配事件 selectionChange
{ label: '操作', dataCode: 'act'}, // 操作项 可无
{ label: '日期', // label 表列title 必
dataCode: 'date', // dataCode data展示项 必
width: 160 // width 列属性 非必需填
'min-width': 100 // width 列属性 非必需填 (带'-'的属性 需要用''括起来。下同)
fixed: 'true|left|right' // fixed 列属性 非必需填 列是否固定在左侧或者右侧,true 表示固定在左侧
'header-align': 'left|center|right' // header-align 列属性 列头对齐方式 非必需填
align: 'left|center|right' // header-align 列属性 列内容对齐方式 非必需填 默认: left
sortable: 'true|false| 'custom'' // sortable 列属性 非必需填 是否可以排序 搭配事件 sortChange
'show-overflow-tooltip': true
... 等等 属性同 el-table 官网2.15 版本
},
],
data:
event:
selectionChange: // 选择事件 []
sortChange: // 排序事件 e: {order : 'ascending|descending|null', prop: columnConfig.dataCode }
clickRow: // 点击行事件
使用如下:
javascript
<uiTable
:config="tableConfig"
:columnConfig="columnConfig"
:data="tableData"
>
<!-- 需要特别处理的列 用slot, 直接展示值的则不做处理 -->
<template #status="{ row, rowIndex }">
<div class="status-box1" v-if="row.status == 0"><span>禁用</span></div>
<div class="status-box2" v-else-if="row.status == 1"><span>有效</span></div>
</template>
<template #act="{row}">
<div class="act-td-box">
<el-button type="primary" size="mini" v-if="row.status !== 2"
@click="toModify(row.id)">修改
</el-button>
<el-button type="danger" size="mini" v-if="row.status !== 2"
@click="toDelete(row.id)">删除
</el-button>
</div>
</template>
</uiTable>
// js
tableConfig: {
size: 'mini',
'tooltip-effect': 'dark',
'highlight-current-row': true
},
columnConfig: [
{ dataCode: 'selection', align: 'center', width: 60, fixed: 'left'},
{ label: '最迟采集时间', dataCode: 'xxxx4', 'min-width': 160},
{ label: '更改标记', dataCode: 'tag', 'min-width': 100},
{ label: '操作', dataCode: 'act', 'min-width': 220, fixed: 'right'},
]