麻煩點
- 在使用element-ui的
el-table
組件時,需要手工寫入大量el-table-column
,費時費力;在需要用到Scoped slot
時,需要創建el-table-column
,并在其中加入template標簽(用法:<template slot-scope="props">/*...*/</template>
)。
- 不支持可配置
改善點
- 全部配置化,自動生成
el-table-column
,其中columns
對應El-Table-column Attributes,props
對應El-Table Attributes,El-Table原有事件照原先用法使用即可
- 通過render進行了封裝,首先
el-table
原有功能全部支持且用法不變
- 至于
Scoped slot
用法,則加入renderCell
配置項進行支持
- 支持多級表頭
用法示例
// test
<template>
<div class="test">
<config-table
:columns="tableColumns"
:loading="loading"
:props="tableProps"
@cell-click="handleCellClick"
@row-click="handleCellClick"
ref="cRef"
>
<div slot="append">測試slot append</div>
</config-table>
<el-button @click="toggle">更改選中狀態</el-button>
</div>
</template>
<script>
import configTable from './index'
export default {
name: 'test',
components: {
configTable
},
data() {
return {
loading: false,
tableProps: {
'show-summary': true,
'highlight-current-row': true,
data: [
{
a: '123',
b: '哈嘍',
c: '高層',
d: 'm2',
e: 234,
f: 11.1,
g: 12345
},
// {
// a: 'tyhj',
// b: '中國',
// c: '中層',
// d: 'kilo',
// e: 1111,
// f: 33.3,
// g: 456
// }
]
},
tableColumns: [
{
type: 'selection',
width: 100
},
{
label: '項目編碼',
prop: 'a',
}, {
label: '項目名稱',
prop: 'b',
}, {
label: '項目特征',
prop: 'c',
}, {
label: '單位',
prop: 'd',
minWidth: '200px',
formatter: (row, column) => `單位:${row[column.property]}`,
renderHeader: (h, d) => `我是${d.column.label}`, // 對應El-Table-column Attributes render-header
// 優先級高于formatter,相當于el-table-column中作用域插槽
renderCell: (h, props) => h('span', `${props.column.label}ing:${props.row[props.column.property]}`) // 這是自定義的El-Table-column Attributes,對應scopedSlot!!!
}, {
label: '基準模型',
prop: '',
render: null,
data: null,
children: [
{
label: '工程量',
prop: 'e',
}, {
label: '綜合單價',
prop: 'f',
}, {
label: '綜合合價',
prop: 'g',
}
]
}
],
}
},
methods: {
handleCellClick(...args) {
console.log(args)
},
toggle() {
this.$refs.cRef.$refs.ref.toggleRowSelection(this.tableProps.data[0])
},
}
}
</script>
<style lang="scss" scoped>
.test {
}
</style>
效果圖
源碼
<script>
export default {
name: 'config-table',
props: {
loading: {
type: Boolean,
default: () => false
},
props: { // 對應El-Table Attributes
required: true,
type: Object
},
columns: { // 對應El-Table-column Attributes
required: true,
type: Array,
default: () => []
},
},
render(createElement) {
const render = (h, data) => {
data = Array.isArray(data) ? data : [data]
return data.map(col => {
const { children } = col
const props = {
...col
}
const hasChildren = Array.isArray(children) && children.length
const hasCellRender = typeof col.renderCell === 'function'
let cS = []
if (hasChildren) {
cS = render(h, children)
}
const colProps = {
props
}
if (hasCellRender) {
colProps.scopedSlots = {
default(ps) {
return col.renderCell(h, ps) // 通過renderCell,支持scopedSlots
}
}
}
return h('el-table-column', colProps, hasChildren ? cS : []) // 通過children屬性,支持多級表頭
})
}
return createElement('el-table', {
class: 'config-table',
props: {
...this.props
},
on: {
...this.$listeners // 支持El-Table 原有所有Events
},
directives: [
{
name: 'loading',
value: this.loading // 支持loading
}
],
ref: 'ref', // 通過這個ref,對應El-Table Methods
}, render(createElement, this.columns).concat(createElement('template', { slot: 'append' },this.$slots.append))) // 支持El-Table slot append
}
}
</script>
<style lang="scss" scoped>
.config-table {
}
</style>