preface
Data-driven tables reduce tedious code.
code
Props part
tableColumn: {
type: Array.default: () = >[{label: "Serial number".align: "center".width: 50.type: "index"}, {prop: "name".label: "Name".align: "center"}, {prop: "age".label: "Age".align: "center"}, {prop: "sex".label: "Gender".align: "center",}]},tableData: {
type: Array.default: () = >[{name: "Slippers in your face.".age: 18.sex: "Male",}]},size: {
type: String.default: "medium",},stripe: {
type: Boolean.default: false,},border: {
type: Boolean.default: false,},fit: {
type: Boolean.default: true,},showHeader: {
type: Boolean.default: true,},headerCellStyle: {
type: Function.default: (/*{ row, column, rowIndex, columnIndex }*/) = > {
return { color: "# 000"}; }},cellStyle: {
type: Function.default: (/** {row, column, rowIndex, columnIndex}*/) = > {
return { color: "# 333"}; }},pagination: {
type: Object.default: () = > ({
current: 1.size: 10.total: 0,})},pageSizes: {
type: Array.default: () = > [10.20.30.50],},Copy the code
Render part
render(h) {
const {
tableData,
size,
stripe,
border,
fit,
showHeader,
headerCellStyle,
cellStyle,
sortChange,
select,
selectAll,
selectionChange,
tableColumn,
/ / paging
pagination: { current, size: pageSize, total },
pageSizes,
sizeChange,
currentChange,
} = this;
return h(
"div",
{
class: {
"render-table": true,
},
},
[
h(
"el-table",
{
props: {
data: tableData,
size: size,
stripe: stripe,
border: border,
fit: fit,
"show-header": showHeader,
"header-cell-style": headerCellStyle,
"cell-style": cellStyle,
},
on: {
"sort-change": sortChange,
select: select,
"select-all": selectAll,
"selection-change": selectionChange,
},
style: {
width: "100%",}},this.renderColumn(tableColumn, h)
),
h("el-pagination", {
props: {
"current-page": current,
"page-size": pageSize,
"page-sizes": pageSizes,
total: total,
layout: "total, sizes, prev, pager, next, jumper",},on: {
"size-change": sizeChange,
"current-change": currentChange,
},
style: {
"text-align": "right"."margin-top": "10px",},}),]); }Copy the code
The methods of
createColumn(column) {
return [
"el-table-column",
{
props: {
...this.attributesColumn(column),
},
},
];
},
createScopedSlot({ scopedSlots, prop }, h) {
let { tag, text, textStyle, click, slot } = scopedSlots;
let { isTrue, isFunc, columnClick, scopedSlotText } = this;
return {
scopedSlots: {
default: (props) = > {
const value = props["row"][prop];
if (slot) {
return h(
"div".this.$scopedSlots["opration"] ({row: props["row"]})); }return h(
tag,
{
on: isTrue(click) ? { click: columnClick(props) } : {},
style:
isFunc(textStyle) &&
textStyle(props["$index"] + 1, value, props["row"]), }, scopedSlotText(text, value, props) ); ,}}}; },renderColumn(columns, h) {
if(! columns || ! columns.length) {return;
}
let tableColumn = [];
columns.forEach((item) = > {
let { scopedSlots } = item;
let column = this.createColumn(item);
let vNode;
if (this.notEmpty(scopedSlots)) {
column[1] = {
...column[1],... this.createScopedSlot(item, h), }; vNode = h(... column); }else{ vNode = h(... column,this.renderColumn(item.children, h));
}
tableColumn.push(vNode);
});
return tableColumn;
},
attributesColumn(column) {
const attr = [
"type"."label"."prop"."width"."align"."fixed"."sortable"."scopedSlots",];let obj = {};
attr.forEach((prop) = > {
column[prop] && (obj[prop] = column[prop]);
});
return obj;
},
notEmpty(obj) {
if (typeof obj === "object" && JSON.stringify(obj) ! = ="{}") {
return true;
}
return false;
},
isTrue(v) {
return v === true;
},
isDef(v) {
return v === undefined;
},
isFunc(v) {
return typeof v === "function";
},
scopedSlotText(text, value, column) {
const { $index: index, row } = column;
if (!this.isDef(text)) {
return this.isFunc(text) ? text(index, value, row) : text;
}
return value;
},
// Custom column click
columnClick(scope) {
let { $index, row } = scope;
return () = > {
this.$emit("columnClick", {
index: $index, ... row, }); }; },// This event is triggered when the table's sorting criteria change
sortChange({ order, prop }) {
this.$emit("sortChange", { order, prop });
},
// The event that is triggered when the user manually checks the Checkbox of a data row
select(selection, row) {
this.$emit("select", selection, row);
},
// This event is triggered when the user manually checks all checkboxes
selectAll(selection) {
this.$emit("select-all", selection);
},
// This event is triggered when the selection changes
selectionChange(selection) {
this.$emit("selection-change", selection);
},
// When pageSize changes
sizeChange(size) {
this.$emit("pagination-change", {
current: this.pagination.current,
size,
});
},
// When currentPage changes
currentChange(current) {
this.$emit("pagination-change", {
current,
size:this.pagination.size,
});
},
Copy the code
usage
Basic usage
<render-table />
Copy the code
The effect
<render-table
:border="true"
:tableColumn="tableColumn"
:tableData="tableData"
/>
tableColumn: [
{
label: "Serial number".type: "index".width: 50.align: "center"}, {label: "Students".prop: "student".align: "center"}, {label: "Mathematics".align: "center".prop: "math"}, {label: "Chinese".align: "center".prop: "language"}, {label: "English".prop: "english".align: "center"],},tableData: [{student: "Zhang".math: 60.language: 60.english: 60}, {student: "Fifty".math: 66.language: 80.english: 77],},Copy the code
Pass data to the table by setting tableColumn, tableData properties.
The effect
multi-select
<render-table
:border="true"
:tableColumn="tableColumn"
:tableData="tableData"
@select='select'
@select-all='selectAll'
@selection-change='selectionChange'/ > {// label:
type: "selection".width: 50.align: "center",},Copy the code
To implement multiple selection, simply set the type property value to Selection. Methods such as SELECT, select-all, and selection-change are also provided. The usage is the same as that of el-table.
The effect
Header nesting is supported
{
label: "Performance".align: "center".children: [{label: "Mathematics".align: "center".prop: "math"}, {label: "Chinese".align: "center".prop: "language"}, {label: "English".prop: "english".align: "center",}]},Copy the code
To implement header nesting, add the children attribute to tableColumn.
The effect
Support for custom columns
{
label: "Students".prop: "student".align: "center".scopedSlots: {tag:'span'.text:'Custom'}},Copy the code
To implement custom columns you need to add scopedSlots and set tag and text. In the command, tag and text are user-defined display text. Text can be a string or a function
When text is a function
{
label: "Students".prop: "student".align: "center".scopedSlots: {tag:'span'.text:(index,value,row) = >{
returnvalue; }}},Copy the code
The effect
If you need to set a style, you have textStyle
{
label: "Students".prop: "student".align: "center".scopedSlots: {tag:'span'.text:(index,value,row) = >{
return value;
},
textStyle:(index,value,row) = >{
return {color:'red'}}}},Copy the code
The effect
Need to listen for click callbacks, columnClick.
<render-table
:border="true"
:tableColumn="tableColumn"
:tableData="tableData"
@select="select"
@select-all="selectAll"
@selection-change="selectionChange"
@columnClick="columnClick"/ > {label: "Students".prop: "student".align: "center".scopedSlots: {tag:'span'.text:(index,value,row) = >{
return value;
},
textStyle:(index,value,row) = >{
return {color:'red'}},click:true}},columnClick(row) {
console.log(row);
},
Copy the code
In general, table clicks are about actions, like editing, you can do that.
{
label:'operation'.align:'center'.scopedSlots: {tag:'el-button'.click:true.text:'edit'}}Copy the code
The effect
It doesn’t feel like a lot to get here, but there are still some problems operating here. If you only use tag+text+click, you can’t do some complex operations, such as edit, delete, view, etc. That’s where the slot property comes in.
<render-table
:border="true"
:tableColumn="tableColumn"
:tableData="tableData"
@select="select"
@select-all="selectAll"
@selection-change="selectionChange"
@columnClick="columnClick"
>
<template #opration='{row}'>
<el-button @click="edit(row)">The editor</el-button>
<el-button>To view</el-button>
<el-button>delete</el-button>
</template>
</render-table>
{
label:'operation'.align:'center'.scopedSlots: {slot:true}}Copy the code
The effect
attribute
The same usage as el-table is not specified.
table
data: tableData,
size: size,
stripe: stripe,
border: border,
fit: fit,
"show-header": showHeader,
"header-cell-style": headerCellStyle,
"cell-style": cellStyle,
Copy the code
column
"type"."label"."prop"."width"."align"."fixed"."sortable"."scopedSlots".Copy the code
scopedSlots
Tag: Specifies the element tag. This parameter is mandatory if customization is required. Text: Custom text rendering, which can be string/function.functionThree parameters will be receivedindex.value.row
textStyle: Custom stylefunctionReceive three parametersindex.value.row, the return valueobject
click: Whether you need to click,true/false
slot: Open the slot,true/false
Copy the code
pagination
"current-page": current,
"page-size": pageSize,
"page-sizes": pageSizes,
total: total,
Copy the code
The event
columnClick(row) // Custom click callback
// The same as el-tableSortChange, Select, selectAll, selectionChange// Paging callback
pagination-change({current,size})
Copy the code