Element-ui Table 封装
Element Table
0. 前言
公司技术选型: vue + element-ui
后端开发也是用封装的 UI 组件,CSS 样式(你懂得 ~。~)。那就少让人家写HTML、CSS
1. 添加 `columns` 属性,来完成类似 antd 的功能
<template>
<table-client :data="data" :columns="columns" />
</template>
<script>
export default {
data() {
return {
columns: [
{ type: "selection", align: "center" },
{ type: "index", label: "序号", index: index => index, align: "center" },
{ prop: "date", label: "日期", align: "center", sortable: true }
],
data: [
{ date: "2016-05-02", name: "王1", address: "金沙江路 1518 弄", header: 1 },
{ date: "2016-05-04", name: "王2", address: "金沙江路 1517 弄", header: 2 }
]
};
}
};
</script>
代码
<script>
import Vue from "vue";
import Component from "vue-class-component";
@Component({
props: {
columns: {
type: Array,
default: () => []
}
}
})
export default class Table extends Vue {
get ref() {
return this.$children[0];
}
render(h) {
const Col = () =>
this.columns.map(item => {
const { render, renderHead, ...attrs } = item;
const prop = { attrs, scopedSlots: {} };
if (render) {
prop.scopedSlots.default = function(props) {
return render(props, h);
};
}
if (renderHead) {
prop.scopedSlots.header = function(props) {
return renderHead(props, h);
};
}
return <el-table-column {...prop} />;
});
return (
<el-table
{...{
attrs: this.$attrs,
on: this.$listeners
}}
>
<Col />
{this.$slots.default}
<template slot="append">{this.$slots.append}</template>
</el-table>
);
}
}
</script>
简化优化
<script>
export default {
props: {
columns: {
type: Array,
default: () => []
}
},
computed: {
ref() {
return this.$refs.table;
}
},
render() {
const Col = () =>
this.columns.map(item => {
const { component, render, on, ...attrs } = item;
const prop = { attrs, on, scopedSlots: {} };
if (render) {
if (typeof render === "function") {
prop.scopedSlots.default = props => render(props);
} else {
Object.keys(render).forEach(key => {
prop.scopedSlots[key] = props => render[key](props);
});
}
}
if (component) {
return <component is={component} {...prop} />;
}
return <el-table-column {...prop} />;
});
const Slots = () => {
const slots = this.$scopedSlots || {};
return Object.keys(slots).map(slot => {
if (slot === "default") {
return slot.default;
}
return <template slot={slot}>{slots[slot]}</template>;
});
};
return (
<el-table ref="table" {...{ attrs: this.$attrs, on: this.$listeners }}>
<Col />
<Slots />
</el-table>
);
}
};
</script>
测试
<template>
<div class="home">
<el-button @click="clear">取消选中</el-button>
<el-button @click="toggleSelection([data[1], data[2]])">
取消第二、三行选中
</el-button>
<table-client
ref="table"
tooltip-effect="dark"
style="width: 100%; margin-top: 15px;"
:data="data"
:columns="columns"
:default-sort="{ prop: 'date', order: 'descending' }"
fit
lazy
stripe
border
@selection-change="handleSelectionChange"
>
<el-table-column label="Date" prop="date" />
<div slot="append" class="cell" style="padding: 8px 0;">1</div>
</table-client>
<div style="text-align: right;margin-top: 12px;">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="currentPage"
:page-sizes="[100, 200, 300, 400]"
:page-size="100"
layout="sizes, prev, slot, next"
:total="1000"
>
<template>
<ul class="el-pager">
<li class="number">壹</li>
<li class="number">貳</li>
<li class="number active">参</li>
<li class="number">肆</li>
<li class="number">伍</li>
</ul>
</template>
</el-pagination>
</div>
</div>
</template>
<script>
import TableClient from "@/components/Table-client";
export default {
name: "Home",
components: { TableClient },
data() {
return {
currentPage: 1,
multipleSelection: [],
columns: [
{
type: "selection",
align: "center"
},
{
type: "index",
label: "序号",
index: index => index,
width: "80",
align: "center"
},
{
prop: "date",
label: "日期",
width: "180",
align: "center",
sortable: true
},
{ prop: "name", label: "姓名", width: "180" },
{ prop: "address", label: "地址" },
{
prop: "header",
label: "自定义头部",
render: ({ column, $index }) => {
return (
<div>
{column.label}-{$index}
</div>
);
}
},
{
prop: "op",
label: "操作",
render: {
default: ({ row }) => (<div>{row.address}</div>),
header: ({ column, $index }) => <div>{column.label}-{$index}</div>
}
}
],
data: [
{
date: "2016-05-02",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄",
header: 1
},
{
date: "2016-05-04",
name: "王小虎",
address: "上海市普陀区金沙江路 1517 弄",
header: 2
},
{
date: "2016-05-01",
name: "王小虎",
address: "上海市普陀区金沙江路 1519 弄",
header: 3
},
{
date: "2016-05-03",
name: "王小虎",
address: "上海市普陀区金沙江路 1516 弄",
header: 4
}
]
};
},
methods: {
handleSizeChange(val) {
console.log(`每页 ${val} 条`);
},
handleCurrentChange(val) {
console.log(`当前页: ${val}`);
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
toggleSelection(rows) {
if (rows) {
rows.forEach(row => {
this.$refs.table.ref.toggleRowSelection(row);
});
} else {
this.clear();
}
},
clear() {
this.$refs.table.ref.clearSelection();
}
}
};
</script>
效果

这是最好的时代!
技术孕育时代,时代造就技术。

浙公网安备 33010602011771号