公司项目目前使用的是element,但是在使用过程中发现elementUI的一些常用组件使用起来比较的繁琐,重复的代码较多,所以就寻思着自己封装一下,简化使用,记录一下封装的其中常用el-table组件,方便以后使用。
const publicComponent = {
components: {
VTable: {
props: {
rootName: [String, Number],
column: Array,
data: Array,
border: {
type: Boolean,
default: true
},
configColumns: Array,
showConfigTable: Boolean,
height: [String, Number],
selectionChange: Function,
sortChange: Function,
rowClick: Function,
select: Function,
selectAll: Function,
cellMouseEnter: Function,
cellMouseLeave: Function,
cellClick: Function,
cellDblclick: Function,
rowContextmenu: Function,
rowDblclick: Function,
headerClick: Function,
currentChange: Function,
headerDragend: Function,
expand: Function
},
data() {
return {
datas: []
};
},
watch: {
data(val) {
this.datas = val;
}
},
render: function(h) {
var self = this.$parent;
var _this = this;
// 当组件有嵌套时,找到使用这个组件的实例
while (self.$parent !== undefined) {
self = self.$parent;
if (self.rootName === this.rootName) {
break;
}
};
var column = this.column === undefined ? self.column : this.column;
var translateMethod = function(methodName, args) {
var alias = methodName.charAt(0).toUpperCase() + methodName.slice(1);
if (this['handle' + alias]) {
this['handle' + alias].apply(this, args);
} else if (this[methodName]) {
this[methodName].apply(this, args);
} else if (self['handle' + alias]) {
self['handle' + alias].apply(self, args);
}
};
var getChildren = function(column, ret = []) {
var resultNode = _this._l(column, function (elt) {
var _default = {headerAlign: 'center'};
var colParams = {};
for (var i in elt) {
colParams[i] = elt[i];
}
colParams = Object.assign(colParams, _default);
if (elt.renderCell) {
// 实现template
return h('ElTableColumn', {
props: colParams,
scopedSlots: {
default: function (val) {
if (elt.renderCell) {
return elt.renderCell(h, val);
}
}
}
}, [elt.children ? getChildren(elt.children) : ''])
} else {
return h('ElTableColumn', {
props: colParams,
}, [elt.children ? getChildren(elt.children) : ''])
}
});
ret.push(resultNode);
return ret
};
return h('ElTable', {
props: {
border: this.border,
data: this.data,
height: this.height === undefined ? self.tableHeight : this.height
},
on: {
'selection-change': function(selection) {
translateMethod.call(_this, 'selectionChange', arguments);
},
'select': function(selection, row) {
translateMethod.call(_this, 'select', arguments);
},
'select-all': function(selection) {
translateMethod.call(_this, 'selectAll', arguments);
},
'cell-mouse-enter': function(row, column, cell, event) {
translateMethod.call(_this, 'cellMouseEnter', arguments);
},
'cell-mouse-leave': function(row, column, cell, event) {
translateMethod.call(_this, 'cellMouseLeave', arguments);
},
'cell-click': function(row, column, cell, event) {
translateMethod.call(_this, 'cellClick', arguments);
},
'cell-dblclick': function(row, column, cell, event) {
translateMethod.call(_this, 'cellDblclick', arguments);
},
'row-click': function(row, column, cell, event) {
translateMethod.call(_this, 'rowClick', arguments);
},
'row-contextmenu': function(row, column, cell, event) {
translateMethod.call(_this, 'rowContextmenu', arguments);
},
'row-dblclick': function(row, column, cell, event) {
translateMethod.call(_this, 'rowDblclick', arguments);
},
'header-click': function(row, column, cell, event) {
translateMethod.call(_this, 'headerClick', arguments);
},
'sort-change': function(row, column, cell, event) {
translateMethod.call(_this, 'sortChange', arguments);
},
'filter-change': function(row, column, cell, event) {
translateMethod.call(_this, 'filterChange', arguments);
},
'current-change': function(row, column, cell, event) {
translateMethod.call(_this, 'currentChange', arguments);
},
'header-dragend ': function(row, column, cell, event) {
translateMethod.call(_this, 'headerDragend', arguments);
},
'expand': function(row, column, cell, event) {
translateMethod.call(_this, 'expand', arguments);
}
}
}, [getChildren(column)]);
},
key: new Date().getTime()
}
}
};
export default publicComponent;
使用
<template>
<div class="app">
<v-table :root-name="rootName" :column="column" :data="data"></v-table>
</div>
</template>
<script>
import publicComponent from './publicComponent'
export default {
mixins: [publicComponent],
data() {
return {
column: [],
data: [],
rootName: 'index' // 告诉v-table使用者是谁,适用于多层嵌套的情况下
}
},
created() {
this.data = [
{
date: '2016-05-02',
name: '王小虎',
age: 10,
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
age: 20,
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
age: 28,
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
age: 18,
address: '上海市普陀区金沙江路 1516 弄'
}];
this.column = [
{ type: 'selection', width: 50 },
{ label: '时间', prop: 'date', align: 'center' },
{ label: '年龄', children: [
{ label: '年龄1', prop: 'age' },
{ label: '年龄2', prop: 'age', renderCell(h, scope) {
const { row, column } = scope;
let vColor = 'red';
if (row[column.property] < 20) {
vColor = 'blue'
}
return h('div', { style: { color: vColor } }, row[column.property])
}
},
] },
{ label: '姓名', prop: 'name' },
{ label: '地址', prop: 'address' },
]
},
methods: {
handleSelectionChange(row) {
console.log(row)
}
}
}
</script>
大概就是这样