elementUI 表格组件二次开发
组件使用环境说明 vue2.6 + jsx 基于 es6
demo
<picc-table
:column="includeTable"
:data="includeData" height="auto"
:selection="true"
:number="true"
:showPagination="false"
:single="true">
<template slot="action" slot-scope="{ scope }">
<el-button @click="eventClickDelete(scope)">删除</el-button>
<el-button><a href="http://www.baidu.com" target="_bank">下载</a></el-button>
</template>
</picc-table>
props 说明
@name 表格组件
@param {data} JSON 数据
@param {column} object const tableColumn = [{prop: "contractId",label: "合同ID"},{ prop: "action",label: "操作", slot: "action"}];
@param {showPagination} boolean 是否显示分页
@param {pagination} listQuery: { total: 0, page: 1,limit: 10,importance: undefined, title: undefined, type: undefined, sort: "+id" }
@param {selectable} function 判断是否能选中
@param {number} boolean 是否显示行号
@param {single} Boolean 是否单选
@event onChange 分页请求数据
@event selected 多选
@event currentSelect 单选
组件源码
/**
* @template <picc-table :data="tableData" :column="tableColumn" :pagination="listQuery" @onChange="onPageChange">
<template slot="action" slot-scope="scope">
<el-button type="text" @click="onAddContract(scope)">
添加
</el-button>
</template>
</picc-table>
@name 表格组件
@param {data} JSON 数据
@param {column} object const tableColumn = [{prop: "contractId",label: "合同ID"},{ prop: "action",label: "操作", slot: "action"}];
@param {showPagination} boolean 是否显示分页
@param {pagination} listQuery: { total: 0, page: 1,limit: 10,importance: undefined, title: undefined, type: undefined, sort: "+id" }
@param {selectable} function 判断是否能选中
@param {number} boolean 是否显示行号
@param {single} Boolean 是否单选
@event onChange 分页请求数据
@event selected 多选
@event currentSelect 单选
*/
import Pagination from "@/components/Pagination";
import "./piccTable.scss";
let selectMap = new Map();
export default {
name: "picc-table",
comments: { [Pagination.name]: Pagination },
props: {
data: {
type: Array,
default() {
return [];
} // 数据
},
column: {
type: Array,
defualt() {
return [];
}
},
// 翻页信息
pagination: {
type: Object,
default() {
return {
total: 100,
page: 0,
limit: 20,
pageNo: 0
};
}
},
selection: { type: Boolean, default: false },
// 显示翻页
showPagination: {
type: Boolean, default: true
},
// 返回false 或 true 判断选中
selectable: { type: Function, default() { return new Function() } },
// 高度
height: { type: String, default: "400" },
// 序号
number: { type: Boolean, defualt: false },
single: { type: Boolean, default: false },
},
data() {
return {
radio: ""
};
},
mounted() {
this.init();
},
methods: {
init() {
selectMap = new Map();
this.$refs.table.clearSelection();
},
// TODO: 创建表头
createColumn() {
let children = ({ slot }) => {
if (slot) {
return this.$scopedSlots[slot];
}
};
let col = this.column.map((item = { prop: "", label: "--", align: "center" }, ind) => {
return (
<el-table-column prop={item.prop} label={item.label} show-overflow-tooltip align="center" key={ind} width={item["width"] || "auto"}>
{children(item)}
</el-table-column>
);
});
// 选择框
// 序号
if (this.number) {
col.unshift(<el-table-column
fixed="left"
type="index"
width="50"
label="序号"
align="center"
/>)
}
// 多选
if (this.selection && !this.single) {
col.unshift(<el-table-column
fixed="left"
type="selection"
width="50"
selectable={this.selectable}
/>)
}
// // 单选
if (this.single) {
col.unshift(<el-table-column
fixed="left"
width="50"
label=""
{...{
scopedSlots: {
default: (scope) => {
return <el-radio class="singleRadio" label={scope.row.id} value={this.radio} />
}
}
}}
>
</ el-table-column>)
}
return col;
},
// TODO: 翻页事件
EventOnPagination(data) {
let pagination = Object.assign({ ...this.pagination }, { ...data });
this.$emit("onChange", pagination);
},
// TODO: sync page
SyncEventlimit(data) {
// let limit = { limit: data };
// this.EventOnPagination(pages);
},
// TODO: sync page
SyncEventpage(data) {
// let page = { page: data };
// this.EventOnPagination(page);
},
// 设置选中
setSelected(row) {
let { pageNo } = this.pagination;
if (row && row.length) {
// 判断单选还是多选
selectMap.set(
pageNo,
row.map((item) => {
return item.id;
})
);
} else {
selectMap.delete(pageNo);
}
this.$emit("selected", selectMap);
},
eventSelectionChange() {
},
eventCurrentChange(val) {
this.radio = val.id;
this.$emit('currentSelect', val)
},
// 手动选中
eventSelect(selection) {
this.setSelected(selection);
},
// 全选
eventSelectAll(selection) {
this.setSelected(selection);
}
},
render() {
let { data, pagination, showPagination, height, single } = this;
let showPage = () => {
if (showPagination) {
return <Pagination
total={pagination.total}
page={pagination.page}
limit={pagination.limit}
showHeader={true}
{...{
on: {
"update:limit": this.SyncEventlimit,
"update:page": this.SyncEventpage,
pagination: this.EventOnPagination
}
}}
/>
}
}
return (
<article class='picc-table'>
<el-table
data={data} fit border empty-text="暂无数据" style="width: 100%" height={height}
highlightCurrentRow={single}
class={{ "single": true }}
{...{
ref: "table",
on: {
"select": this.eventSelect,
"select-all": this.eventSelectAll,
"selection-change": this.eventSelectionChange,
"current-change": this.eventCurrentChange
}
}}
>
{this.createColumn()}
</el-table>
{showPage()}
</article >
);
}
};
翻页组件源码 @/components/Pagination
此组件只是为了配合翻页使用
<template>
<div v-if="total > 0" :class="{ hidden: hidden }" class="pagination-container">
<el-pagination
:background="background"
:current-page.sync="currentPage"
:page-size.sync="pageSize"
:layout="layout"
:page-sizes="pageSizes"
:total="total"
v-bind="$attrs"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</template>
<script>
import { scrollTo } from "@/utils/scroll-to";
export default {
name: "Pagination",
props: {
total: {
required: true,
type: Number
},
page: {
type: Number,
default: 1
},
limit: {
type: Number,
default: 10
},
pageSizes: {
type: Array,
default() {
return [10, 20, 30, 50];
}
},
layout: {
type: String,
default: "total, sizes, prev, pager, next, jumper"
},
background: {
type: Boolean,
default: true
},
autoScroll: {
type: Boolean,
default: true
},
hidden: {
type: Boolean,
default: false
}
},
computed: {
currentPage: {
get() {
return this.page;
},
set(val) {
this.$emit("update:page", val);
}
},
pageSize: {
get() {
return this.limit;
},
set(val) {
this.$emit("update:limit", val);
}
}
},
methods: {
handleSizeChange(val) {
this.$emit("pagination", { page: this.currentPage, limit: val });
if (this.autoScroll) {
scrollTo(0, 800);
}
},
handleCurrentChange(val) {
this.$emit("pagination", { page: val, limit: this.pageSize });
if (this.autoScroll) {
scrollTo(0, 800);
}
}
}
};
</script>
<style scoped>
.pagination-container {
background: #fff;
padding: 32px 16px;
}
.pagination-container.hidden {
display: none;
}
</style>
为了隐藏单选时label标签写了些scss, import "./piccTable.scss";
.single{
// 单选
.singleRadio{
.el-radio__label{
display: none;
}
}
}