超级表格组件之render抽象
0.问题
抽象一个复杂表格组件
1.解决方法
借助element自己的renderHeader与上面的大佬写的render函数,可以抽象出来这样一个组件
// tableCom.vue
<template>
<div>
<el-table
empty-text="暂无数据"
ref="table"
:data="tableList"
border
stripe
fit
highlight-current-row
:height="inTableHeight"
@selection-change="selectionChange"
@row-click="rowClick"
:header-cell-style="{ background: 'rgb(1, 97, 90)', color: 'white' }"
>
<!-- 选择框 -->
<el-table-column
v-if="select"
type="selection"
fixed="left"
width="55"
align="center"
/>
<template v-for="(itm, idx) in header">
<!-- 特殊处理列 -->
<el-table-column
v-if="itm.render && !itm.children"
:key="idx"
:renderHeader="itm.renderHeader ? itm.renderHeader : null"
:prop="itm.prop ? itm.prop : null"
:label="itm.label ? itm.label : null"
:width="itm.width ? itm.width : null"
:sortable="itm.sortable ? itm.sortable : false"
:align="itm.align ? itm.align : 'center'"
:fixed="itm.fixed ? itm.fixed : null"
:show-overflow-tooltip="itm.tooltip"
min-width="50"
>
<template slot-scope="scope">
<ex-slot
:render="itm.render"
:row="scope.row"
:index="scope.$index"
:column="itm"
/>
</template>
</el-table-column>
<!-- 二级表头 -->
<el-table-column
:key="idx"
v-if="itm.children"
:label="itm.label ? itm.label : null"
header-align="center"
:renderHeader="itm.renderHeader ? itm.renderHeader : null"
>
<el-table-column
v-for="(child, indexNum) in itm.children"
:key="indexNum"
:renderHeader="child.renderHeader ? child.renderHeader : null"
:prop="child.prop ? child.prop : null"
:label="child.label ? child.label : null"
:width="child.width ? child.width : null"
:sortable="child.sortable ? child.sortable : false"
:align="child.align ? child.align : 'center'"
:fixed="child.fixed ? child.fixed : null"
:show-overflow-tooltip="child.tooltip"
min-width="50"
>
<template slot-scope="scope">
<ex-slot
:render="child.render"
:row="scope.row"
:index="scope.$index"
:column="child"
/>
</template>
</el-table-column>
</el-table-column>
<!-- 正常列 -->
<el-table-column
v-if="!itm.render && !itm.children"
:key="idx"
:renderHeader="itm.renderHeader ? itm.renderHeader : null"
:prop="itm.prop ? itm.prop : null"
:label="itm.label ? itm.label : null"
:width="itm.width ? itm.width : null"
:sortable="itm.sortable ? itm.sortable : false"
:align="itm.align ? itm.align : 'center'"
:fixed="itm.fixed ? itm.fixed : null"
:formatter="itm.formatter"
:show-overflow-tooltip="itm.tooltip"
min-width="50"
/>
</template>
</el-table>
</div>
</template>
<script>
// 自定义内容的组件
var exSlot = {
functional: true,
props: {
row: Object,
render: Function,
index: Number,
column: {
type: Object,
default: null,
},
},
render: (h, context) => {
const params = {
row: context.props.row,
index: context.props.index,
};
if (context.props.column) params.column = context.props.column;
return context.props.render(h, params);
},
};
export default {
components: { exSlot },
props: {
tableList: {
type: Array,
default: () => [],
},
header: {
type: Array,
default: () => [],
},
select: {
type: Boolean,
default: () => false,
},
height: {
type: [Number, String, Function],
default: () => null,
},
},
data() {
return {
inTableHeight: null,
};
},
created() {
//该阶段可以接收父组件的传递参数
this.inTableHeight = this.height;
console.log("slot see", this.$slots); // 看看里面有啥
},
mounted() {
this.$nextTick(() => {
//表格高度自适应浏览器大小
this.changeTableHight();
if (!this.height) {
window.onresize = () => {
this.changeTableHight();
};
}
});
},
destroyed() {
//高度自适应事件注销
window.onresize = null;
},
watch: {
/**
* 数据变化后 高度自适应
*/
tableList() {
this.$nextTick(() => {
this.changeTableHight();
});
},
},
methods: {
/**
* 选择框选择后更改,事件分发
*/
selectionChange(selection) {
this.$emit("selection-change", selection);
},
/**
* 点击事件
*/
rowClick(row, column, event) {
this.$emit("row-click", row, column, event);
},
/**
* 高度自适应
* 当表格展示空间小于460按460px展示,大于的时候高度填充
*/
changeTableHight() {
if (this.height) {
//如果有传进来高度就取消自适应
this.inTableHeight = this.height;
this.$refs.table.doLayout();
return;
}
let tableHeight = window.innerHeight || document.body.clientHeight;
//高度设置
let disTop = this.$refs.table.$el;
//如果表格上方有元素则减去这些高度适应窗口,66是底下留白部分
tableHeight -= disTop.offsetTop + 26;
if (disTop.offsetParent) tableHeight -= disTop.offsetParent.offsetTop;
this.inTableHeight = tableHeight < 460 ? 460 : tableHeight;
//重绘表格
this.$refs.table.doLayout();
},
},
};
</script>
<style>
.changeColorYellow {
color: rgb(206, 206, 169);
}
</style>
2.使用
// testPage.vue
普通表格内容的使用

二级表头使用

3.补充——其他版本的render抽象
上代码
// lineCom.vue
<template>
<div class="lineCom">
<template v-for="(itm, idx) in header">
<div v-if="itm.render" :key="idx">
<ex-slot
:render="itm.render"
:column="itm"
/>
</div>
</template>
</div>
</template>
<script>
// 自定义内容的组件
var exSlot = {
functional: true,
props: {
row: Object,
render: Function,
index: Number,
column: {
type: Object,
default: null,
},
},
render: (h, context) => {
// const params = {
// row: context.props.row,
// index: context.props.index,
// };
// if (context.props.column) params.column = context.props.column;
return context.props.render(h, context.props.column);
},
};
export default {
components: { exSlot },
props: {
header: {
type: Array,
default: () => [],
},
},
};
</script>
// lineComTable.js

// 使用

人生到处知何似,应似飞鸿踏雪泥。

浙公网安备 33010602011771号