Commit b52e633ca637d904b0cddd7831b5d60437692eea

Authored by 刘汉宸
1 parent 2c334740

feat: 优化Table组件

examples/views/docs/component/table.md
... ... @@ -6,7 +6,7 @@
6 6  
7 7 基本参数与ElementUI的`el-table`相同。
8 8  
9   -::: snippet 支持`size`继承
  9 +::: snippet 支持来自表单的`size`继承
10 10  
11 11 ```html
12 12 <template>
... ... @@ -44,23 +44,14 @@ export default {
44 44  
45 45 ```html
46 46 <template>
47   - <el-form size="mini">
48   - <el-row>
49   - <el-col :span="18">
50   - <z-table v-model="tableData" type="editable" border :columns="columns">
51   - <template #column-editor-gender="{ value, onInput }">
52   - <el-radio-group size="mini" :value="value" @input="onInput">
53   - <el-radio-button label="男">男</el-radio-button>
54   - <el-radio-button label="女">女</el-radio-button>
55   - </el-radio-group>
56   - </template>
57   - </z-table>
58   - </el-col>
59   - <el-col :span="6" style="padding-left: 10px">
60   - <pre class="demo-model">{{ tableData }}</pre>
61   - </el-col>
62   - </el-row>
63   - </el-form>
  47 + <z-table v-model="tableData" type="editable" border :columns="columns">
  48 + <template #editor-gender="{ value, onInput }">
  49 + <el-radio-group size="mini" :value="value" @input="onInput">
  50 + <el-radio-button label="男">男</el-radio-button>
  51 + <el-radio-button label="女">女</el-radio-button>
  52 + </el-radio-group>
  53 + </template>
  54 + </z-table>
64 55 </template>
65 56  
66 57 <script>
... ... @@ -68,14 +59,15 @@ export default {
68 59 data() {
69 60 return {
70 61 tableData: [
71   - { name: '张三', age: 31, gender: '男' },
72   - { name: '李四', age: 27, gender: '女' },
73   - { name: '王五', age: 16, gender: '男' },
  62 + { name: '张三', age: 31, gender: '男', remark: '' },
  63 + { name: '李四', age: 27, gender: '女', remark: '' },
  64 + { name: '王五', age: 16, gender: '男', remark: '' },
74 65 ],
75 66 columns: [
76 67 { prop: 'name', label: '姓名', editable: false },
77 68 { type: 'el-input-number', prop: 'age', label: '年龄' },
78 69 { prop: 'gender', label: '性别' },
  70 + { prop: 'remark', label: '备注' },
79 71 ]
80 72 };
81 73 },
... ... @@ -83,4 +75,15 @@ export default {
83 75 </script>
84 76 ```
85 77  
86   -:::
87 78 \ No newline at end of file
  79 +:::
  80 +
  81 +## API
  82 +
  83 +## Attribute 属性
  84 +
  85 +参数|说明|类型|可选值|默认值
  86 +-|-|-|-|-
  87 +data | 表格数据 | Array | - | -
  88 +value | 表格数据(支持v-model) | Array | - | []
  89 +columns | 表格列配置 | Array | - | []
  90 +type | 表格类型 | String | normal、editable | normal
88 91 \ No newline at end of file
... ...
packages/table/editable.vue
... ... @@ -30,23 +30,21 @@
30 30 <el-table :data="tableData | tableDataFilter" :size="tableSize" v-bind="_props" @header-click="onHeaderClick" @cell-click="onCellClick" @cell-dblclick="onCellDblclick">
31 31 <template v-for="(item, index) in columns">
32 32 <el-table-column v-bind="item" :key="index">
33   - <template #header>
34   - <span>{{ item.label }}</span>
35   - </template>
  33 + <slot :name="`header-${item.prop}`" slot="header"></slot>
36 34 <template #default="{ row, column }">
37   - <table-column-cell
38   - :disabled="item.editable === false"
  35 + <cell-editor
  36 + :disabled="disabled || item.editable === false"
39 37 :editable="item.editable !== false && (row.$editable || (tableEditCell.index === row.$index && tableEditCell.prop === item.prop))"
40 38 :type="item.type"
41 39 :value="row[column.property]"
42 40 @input="onCellInput"
43   - @edit-click="onCellDblclick(row, column)"
44   - @edit-confirm="onHeaderClick"
  41 + @edit-click="setEditCell(row, column)"
  42 + @edit-confirm="cancelEditCell"
45 43 >
46   - <template v-if="$scopedSlots[`column-editor-${item.prop}`]">
47   - <slot :name="`column-editor-${item.prop}`" :value="row[column.property]" :onInput="onCellInput"></slot>
  44 + <template v-if="$scopedSlots[`editor-${item.prop}`]">
  45 + <slot :name="`editor-${item.prop}`" :value="row[column.property]" :onInput="onCellInput"></slot>
48 46 </template>
49   - </table-column-cell>
  47 + </cell-editor>
50 48 </template>
51 49 </el-table-column>
52 50 </template>
... ... @@ -62,16 +60,12 @@ export default {
62 60 name: 'TableEditable',
63 61 extends: TableNormal,
64 62 components: {
65   - tableColumnCell: {
  63 + cellEditor: {
66 64 props: {
67 65 value: [String, Number, Array, Object],
68 66 type: { type: String, default: 'el-input' },
69 67 editable: Boolean,
70 68 disabled: Boolean,
71   - showHandler: {
72   - type: Boolean,
73   - default: true,
74   - },
75 69 },
76 70 watch: {
77 71 editable(val) {
... ... @@ -84,7 +78,7 @@ export default {
84 78 },
85 79 render(h) {
86 80 if (this.editable) {
87   - let editRender = [
  81 + let editorRender = [
88 82 h(this.type, {
89 83 props: { value: this.value, size: 'mini' },
90 84 on: {
... ... @@ -95,21 +89,21 @@ export default {
95 89 }),
96 90 ];
97 91 if (this.$scopedSlots.default) {
98   - editRender = [this.$scopedSlots.default()];
  92 + editorRender = [this.$scopedSlots.default()];
99 93 }
100   - if (this.showHandler !== false) {
  94 + if (!this.disabled) {
101 95 const handlerItems = [h('i', { attrs: { title: '确定', class: 'el-icon-check' }, on: { click: () => this.$emit('edit-confirm') } })];
102 96 // handlerItems.push(h('i', { attrs: { title: '取消', class: 'el-icon-close' }, on: { click: () => this.$emit('edit-confirm') } }));
103 97 const handler = h('span', handlerItems);
104   - editRender.push(handler);
  98 + editorRender.push(handler);
105 99 }
106   - return h('span', { class: 'z-table-column__cell-editable' }, editRender);
  100 + return h('span', { class: 'z-table-column__cell-editable' }, editorRender);
107 101 }
108   - const defauleRender = [this.value];
109   - if (!this.disabled && this.showHandler !== false) {
110   - defauleRender.push(h('i', { attrs: { title: '编辑', class: 'el-icon-edit' }, on: { click: () => this.$emit('edit-click') } }));
  102 + const valueRender = [h('span', this.value)];
  103 + if (!this.disabled) {
  104 + valueRender.push(h('i', { attrs: { title: '编辑', class: 'el-icon-edit' }, on: { click: () => this.$emit('edit-click') } }));
111 105 }
112   - return h('span', { class: 'z-table-column__cell-editable' }, defauleRender);
  106 + return h('span', { class: 'z-table-column__cell-editable' }, valueRender);
113 107 },
114 108 },
115 109 },
... ... @@ -126,6 +120,8 @@ export default {
126 120 return [];
127 121 },
128 122 },
  123 + clickable: Boolean,
  124 + disabled: Boolean,
129 125 ...tableProps,
130 126 },
131 127 watch: {
... ... @@ -146,21 +142,30 @@ export default {
146 142 return value.map((item, index) => ({ ...item, $index: index }));
147 143 },
148 144 },
149   - // mounted() {
150   - // console.log(this.$scopedSlots);
151   - // },
152 145 methods: {
153 146 onHeaderClick() {
154   - this.tableEditCell = {};
  147 + if (this.clickable) {
  148 + this.cancelEditCell();
  149 + }
155 150 },
156   - onCellClick(row, column, cell, event) {
157   - if (row.$index !== this.tableEditCell.index || column.property !== this.tableEditCell.prop) {
158   - this.tableEditCell = {};
  151 + onCellClick(row, column) {
  152 + if (this.clickable) {
  153 + if (row.$index !== this.tableEditCell.index || column.property !== this.tableEditCell.prop) {
  154 + this.tableEditCell = {};
  155 + }
159 156 }
160 157 },
161   - onCellDblclick(row, column, cell, event) {
  158 + onCellDblclick(row, column) {
  159 + if (this.clickable) {
  160 + this.setEditCell(row, column);
  161 + }
  162 + },
  163 + setEditCell(row, column) {
162 164 this.tableEditCell = { index: row.$index, prop: column.property };
163 165 },
  166 + cancelEditCell() {
  167 + this.tableEditCell = {};
  168 + },
164 169 onCellInput(value) {
165 170 const tableData = cloneDeep(this.tableData);
166 171 const tableRow = tableData[this.tableEditCell.index];
... ...
packages/table/index.js
... ... @@ -19,6 +19,8 @@ export default {
19 19 return [];
20 20 },
21 21 },
  22 + clickable: Boolean,
  23 + disabled: Boolean,
22 24 ...tableProps,
23 25 },
24 26 render(h) {
... ...
packages/table/normal.vue
... ... @@ -29,8 +29,5 @@ export default {
29 29 return this.size || this._elFormItemSize || (this.elForm || {}).size || (this.$ELEMENT || {}).size;
30 30 },
31 31 },
32   - mounted() {
33   - // console.log(this);
34   - },
35 32 };
36 33 </script>
... ...