preface
In our daily development, we often use table components. Today, we will learn about its specific implementation. In fact, it is not the same. Ha ha, today also used a different theme, just found.
usage
Next, let’s look at the use of a very familiar table. In fact, in order to distinguish, I’m going to replace el with my; Then let’s implement the my-table and my-table-column components.
<my-table :data="tableData" style="width: 100%">
<my-table-column prop="name" label="Name"></my-table-column>
<my-table-column prop="date" label="Date"></my-table-column>
<my-table-column prop="address" label="Address"></my-table-column>
<my-table-column prop="opreation" label="Operation">
<span slot-scope="scope">{{ scope.row.name }}</span>
</my-table-column>
</my-table>
Copy the code
implementation
The source code for the Table component of Element-UI is too complex. Just to get a rough idea of how this works, let’s implement a demo version.
Train of thought
- To render a table, mount the my-table-column component first and then the My-table component.
- Each time you create a my-table-column component, you need to save all the header information and create a method to render each item of the table. If the header function slot content exists, the data is passed through the scope slot to the outer layer
- Finally, in the my-table component, render the table
Code implementation
My – table – column components
<script>
import { store } from "./index";
export default {
props: ["prop"."label"].created() {
// Set the header information
let item = {
prop: this.prop,
label: this.label,
};
item.renderCell = (data) = > {
let children = null;
// Does the table header have default slot content
if (this.$scopedSlots.default) {
// Use the scope slot to pass each row of data to the outside
children = this.$scopedSlots.default(data);
} else {
// The value of the key corresponding to an item in the array according to the header property
const { row, column } = data;
children = row[column.prop];
}
return <div>{children}</div>;
};
store.columns.push(item);
},
render(h) {
return h("div".this.$slots.default);
// return <td>12</td>;}}; </script>Copy the code
Store instance
import Vue from 'vue'
// Very crudely use a vue instance to store the header information globally
const data = {
columns: [],}const store = new Vue({
data: data
})
export {
store
}
Copy the code
My – table component
<script>
import { store } from "./index";
export default {
props: {
// Incoming data source
data: {
type: Array.default: () = > {
return[]; }},},created() {
store.columns.length = 0;
},
render() {
// Use JSX syntax
return (
<div>{/* my-table-column default slot contents, default hidden do not display */}<div style={{ display: "none}} ">{this.$slots.default}</div>
<table cellspacing="0" cellpadding="0">{/* Table header rendering, traversing the array of table header rendering */}<thead>
<tr>
{store.columns.map((item) => (
<th>{item.label}</th>
))}
</tr>
</thead>{/* Table content rendering, 1. Preferred traversal of incoming data sources, 2. Render the contents of each TD according to the method stored in the table header. 3.<tbody>
{this.data.map((item) => {
return (
<tr>{store.columns.map((column) => { const columnData = { ... column }; const data = { column: columnData, row: item, }; return<td>{column.renderCell(data)}</td>;
})}
</tr>
);
})}
</tbody>
</table>
</div>); }}; </script>Copy the code
The last
Find element-UI is a relatively powerful component library, use free time, understand a little bit of source content, or there will be harvest, finally, everyone to study ~