Commit 86a49e4b8e35e8a7ee2d17a1d14a4dd72f871cac
1 parent
6ea31861
Exists in
master
and in
1 other branch
优化新式表格编辑事件
Showing
2 changed files
with
73 additions
and
36 deletions
Show diff stats
examples/views/page/other.vue
| ... | ... | @@ -13,8 +13,9 @@ |
| 13 | 13 | <template> |
| 14 | 14 | <div> |
| 15 | 15 | <pre>{{ tableData }}</pre> |
| 16 | - <eg-table v-model="tableData" :list="option.list" :tableProps="{ border: true }" editable @cell-edit="onCellEdit"> | |
| 17 | - <el-table-column type="selection"></el-table-column> | |
| 16 | + <eg-table v-model="tableData" :list="option.list" :tableProps="{ border: true }" editable | |
| 17 | + @cell-edit="onCellEdit" @row-new="onRowNew" @row-edit="onRowEdit" @row-delete="onRowDelete" | |
| 18 | + > | |
| 18 | 19 | <template #value-location-locationMin="{ value }"> |
| 19 | 20 | <el-tag v-if="value" size="mini" disable-transitions>{{ value }}</el-tag> |
| 20 | 21 | </template> |
| ... | ... | @@ -161,8 +162,17 @@ export default { |
| 161 | 162 | handleGetValue() { |
| 162 | 163 | this.$refs.form.validate(); |
| 163 | 164 | }, |
| 164 | - onCellEdit(e) { | |
| 165 | - console.log(e) | |
| 165 | + onCellEdit(data) { | |
| 166 | + console.log('cell-edit', data); | |
| 167 | + }, | |
| 168 | + onRowNew(data) { | |
| 169 | + console.log('row-new', data); | |
| 170 | + }, | |
| 171 | + onRowEdit(data) { | |
| 172 | + console.log('row-edit', data); | |
| 173 | + }, | |
| 174 | + onRowDelete(data) { | |
| 175 | + console.log('row-delete', data); | |
| 166 | 176 | } |
| 167 | 177 | } |
| 168 | 178 | } | ... | ... |
examples/views/page/table-new/index.vue
| ... | ... | @@ -7,14 +7,16 @@ |
| 7 | 7 | <template> |
| 8 | 8 | <div @keyup.enter="tableEditCell = {}"> |
| 9 | 9 | <div style="padding-bottom: 10px;"> |
| 10 | - <el-button @click="handleNew" size="mini">新增</el-button> | |
| 10 | + <el-button @click="handleNew" size="mini" v-if="!rowEdit">新增</el-button> | |
| 11 | 11 | <el-button @click="handleEdit" size="mini" v-if="!rowEditable && tableSelection.length > 0">编辑</el-button> |
| 12 | 12 | <el-button @click="handleSave" size="mini" type="primary" v-if="rowEditable">完成</el-button> |
| 13 | - <el-button @click="handleCancel" size="mini" type="plain" v-if="rowNew">取消</el-button> | |
| 13 | + <el-button @click="handleCancel" size="mini" type="plain" v-if="rowNew && !rowEdit">取消</el-button> | |
| 14 | + <el-button @click="handleDelete" size="mini" type="danger" v-if="tableSelection.length > 0">删除</el-button> | |
| 14 | 15 | </div> |
| 15 | 16 | <el-table class="eagle-table" ref="table" :data="tableData" v-bind="{ size: 'small', ...tableProps }" |
| 16 | 17 | v-on="tableEvents" @cell-dblclick="onCellDblclick" @selection-change="onSelectionChange" |
| 17 | 18 | > |
| 19 | + <el-table-column type="selection" :selectable="r => rowNew ? r.$new : true"></el-table-column> | |
| 18 | 20 | <!-- 默认表格插槽 --> |
| 19 | 21 | <slot name="default"></slot> |
| 20 | 22 | <!-- 根据配置列表生成表格列 --> |
| ... | ... | @@ -57,6 +59,17 @@ |
| 57 | 59 | import { cloneDeep, get, set } from '../form-new/util'; |
| 58 | 60 | import CellEditable from './cell-editable'; |
| 59 | 61 | |
| 62 | +const listHasKey = (list, name) => { | |
| 63 | + let result = false; | |
| 64 | + for (const row of list) { | |
| 65 | + if (row[name]) { | |
| 66 | + result = true; | |
| 67 | + break; | |
| 68 | + } | |
| 69 | + } | |
| 70 | + return result; | |
| 71 | +} | |
| 72 | + | |
| 60 | 73 | export default { |
| 61 | 74 | name: 'TableNew', |
| 62 | 75 | components: { CellEditable }, |
| ... | ... | @@ -92,37 +105,27 @@ export default { |
| 92 | 105 | computed: { |
| 93 | 106 | // 表格实体 |
| 94 | 107 | instance: { |
| 95 | - get() { | |
| 96 | - return this.$refs.table; | |
| 97 | - } | |
| 108 | + get() { return this.$refs.table; } | |
| 98 | 109 | }, |
| 99 | 110 | // 行编辑状态 |
| 100 | 111 | rowEditable() { |
| 101 | - let result = false; | |
| 102 | - for (const row of this.tableData) { | |
| 103 | - if (row.$editable) { | |
| 104 | - result = true; | |
| 105 | - break; | |
| 106 | - } | |
| 107 | - } | |
| 108 | - return result; | |
| 112 | + return listHasKey(this.tableData, '$editable'); | |
| 109 | 113 | }, |
| 110 | 114 | // 存在新行 |
| 111 | 115 | rowNew() { |
| 112 | - let result = false; | |
| 113 | - for (const row of this.tableData) { | |
| 114 | - if (row.$new) { | |
| 115 | - result = true; | |
| 116 | - break; | |
| 117 | - } | |
| 118 | - } | |
| 119 | - return result; | |
| 116 | + return listHasKey(this.tableData, '$new'); | |
| 117 | + }, | |
| 118 | + // 存在编辑行 | |
| 119 | + rowEdit() { | |
| 120 | + return listHasKey(this.tableData, '$edit'); | |
| 120 | 121 | } |
| 121 | 122 | }, |
| 122 | 123 | watch: { |
| 123 | 124 | value: { |
| 124 | 125 | handler(val = []) { |
| 125 | - this.tableData = val.map((o, i) => ({ ...o, $index: i })); | |
| 126 | + this.tableData = val.map((o, i) => { | |
| 127 | + return { ...o, $index: i, $editable: undefined, $new: undefined }; | |
| 128 | + }); | |
| 126 | 129 | }, |
| 127 | 130 | immediate: true |
| 128 | 131 | }, |
| ... | ... | @@ -171,41 +174,65 @@ export default { |
| 171 | 174 | }, |
| 172 | 175 | methods: { |
| 173 | 176 | $_get: get, |
| 177 | + // 处理新增逻辑 | |
| 174 | 178 | handleNew() { |
| 175 | 179 | const tableData = cloneDeep(this.tableData); |
| 176 | 180 | tableData.push({ ...this.tableRowTemplate, $new: true }); |
| 177 | 181 | this.tableEditCell = {}; |
| 178 | - this.emitTableData(tableData); | |
| 182 | + this.tableData = tableData.map((o, i) => ({ ...o, $index: i })); | |
| 179 | 183 | }, |
| 184 | + // 处理编辑逻辑 | |
| 180 | 185 | handleEdit() { |
| 181 | 186 | const tableData = cloneDeep(this.tableData); |
| 182 | 187 | const selectionIndexArr = this.tableSelection.map(i => i.$index); |
| 183 | 188 | tableData.forEach((r, i) => { |
| 184 | 189 | if (selectionIndexArr.includes(r.$index)) { |
| 185 | 190 | tableData[i].$editable = true; |
| 191 | + tableData[i].$edit = true; | |
| 192 | + tableData[i].$new = true; | |
| 186 | 193 | } |
| 187 | 194 | }); |
| 188 | 195 | this.tableEditCell = {}; |
| 189 | - this.emitTableData(tableData); | |
| 196 | + this.tableData = tableData.map((o, i) => ({ ...o, $index: i })); | |
| 190 | 197 | }, |
| 198 | + // 处理保存逻辑 | |
| 191 | 199 | handleSave() { |
| 192 | 200 | const tableData = cloneDeep(this.tableData); |
| 193 | 201 | tableData.forEach((r, i) => { |
| 194 | 202 | delete tableData[i].$editable; |
| 195 | - delete tableData[i].$new; | |
| 196 | 203 | }); |
| 197 | 204 | this.tableEditCell = {}; |
| 198 | - this.emitTableData(tableData); | |
| 205 | + this.tableData = tableData.map((o, i) => ({ ...o, $index: i })); | |
| 206 | + this.$nextTick(() => { | |
| 207 | + this.emitTableData(this.tableData); | |
| 208 | + this.$emit(this.rowEdit ? 'row-edit' : 'row-new', this.tableData.filter(d => d.$new).map(d => { | |
| 209 | + delete d.$new; | |
| 210 | + return d; | |
| 211 | + })); | |
| 212 | + }); | |
| 199 | 213 | }, |
| 214 | + // 处理取消逻辑 | |
| 200 | 215 | handleCancel() { |
| 201 | 216 | let tableData = cloneDeep(this.tableData); |
| 202 | 217 | tableData = tableData.filter(row => !row.$new); |
| 203 | 218 | this.emitTableData(tableData); |
| 204 | 219 | }, |
| 220 | + // 处理删除逻辑 | |
| 221 | + handleDelete() { | |
| 222 | + const tableData = cloneDeep(this.tableData); | |
| 223 | + const selectionIndexArr = this.tableSelection.map(i => i.$index); | |
| 224 | + if (!this.rowNew && !this.rowEdit) { | |
| 225 | + this.$emit('row-delete', this.tableSelection); | |
| 226 | + } | |
| 227 | + this.tableEditCell = {}; | |
| 228 | + this.tableData = tableData.filter((d, i) => !selectionIndexArr.includes(i)).map((o, i) => ({ ...o, $index: i })); | |
| 229 | + }, | |
| 205 | 230 | // 更新表格数据 |
| 206 | 231 | emitTableData(tableData) { |
| 207 | 232 | if (this.$listeners['input']) { |
| 208 | - this.$emit('input', tableData); | |
| 233 | + this.$emit('input', tableData.map((o, i) => { | |
| 234 | + return { ...o, $index: i, $editable: undefined, $new: undefined, $edit: undefined }; | |
| 235 | + })); | |
| 209 | 236 | } else { |
| 210 | 237 | this.tableData = tableData; |
| 211 | 238 | } |
| ... | ... | @@ -224,7 +251,7 @@ export default { |
| 224 | 251 | }, |
| 225 | 252 | // 双击单元格 |
| 226 | 253 | onCellDblclick(row, column, cell, event) { |
| 227 | - if (this.editable) { | |
| 254 | + if (this.editable && !this.rowNew) { | |
| 228 | 255 | this.tableEditCell = { index: row.$index, key: column.property }; |
| 229 | 256 | } |
| 230 | 257 | }, |
| ... | ... | @@ -237,15 +264,15 @@ export default { |
| 237 | 264 | this.tableEditCell = {}; |
| 238 | 265 | if (this.$listeners['cell-edit']) { |
| 239 | 266 | const { tableData } = this.setCellValue({ value, row, key, fullKey }); |
| 240 | - if (this.$listeners['input']) { | |
| 241 | - this.$emit('input', tableData); | |
| 242 | - } | |
| 267 | + this.emitTableData(tableData); | |
| 243 | 268 | this.$emit('cell-edit', { row, key, fullKey, value }); |
| 244 | 269 | } |
| 245 | 270 | }, |
| 246 | 271 | // 表格取消编辑 |
| 247 | 272 | onCellUpdateCancel({ oldValue, value, row, key, fullKey }) { |
| 248 | - this.setCellValue({ value: oldValue, row, key, fullKey }); | |
| 273 | + if (row.$new !== true) { | |
| 274 | + this.setCellValue({ value: oldValue, row, key, fullKey }); | |
| 275 | + } | |
| 249 | 276 | }, |
| 250 | 277 | // 设置表格值 |
| 251 | 278 | setCellValue({ value, row, key, fullKey }) { | ... | ... |