editable.vue
2.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
<template>
<el-table :data="tableData | tableDataFilter" :size="tableSize" v-bind="_props" @header-click="onHeaderClick" @cell-click="onCellClick" @cell-dblclick="onCellDblclick">
<template v-for="(item, index) in columns">
<el-table-column v-bind="item" :key="index">
<template #default="{ row, column }">
<table-column-cell
:editable="row.$editable || (tableEditCell.index === row.$index && tableEditCell.prop === item.prop)"
:type="item.type"
:value="row[column.property]"
@input="onCellInput"
></table-column-cell>
</template>
</el-table-column>
</template>
</el-table>
</template>
<script>
import TableNormal from './normal';
import tableProps from './props';
import { cloneDeep, get, set } from '../utils';
export default {
name: 'TableEditable',
extends: TableNormal,
components: {
tableColumnCell: {
props: {
value: [String, Number, Array, Object],
type: { type: String, default: 'el-input' },
editable: Boolean,
},
watch: {
editable(val) {
if (val && this.type === 'el-input') {
this.$nextTick(() => {
this.$children[0].focus();
});
}
},
},
render(h) {
if (this.editable) {
return h(this.type, {
props: { value: this.value, size: 'mini' },
on: {
input: value => {
this.$emit('input', value);
},
},
});
}
return h('span', this.value);
},
},
},
props: {
value: {
type: Array,
default() {
return [];
},
},
columns: {
type: Array,
default() {
return [];
},
},
...tableProps,
},
data() {
return {
tableData: this.value,
tableRowTemplate: { $editable: true }, // 行数据模板
tableEditCell: {}, // 正在编辑的单元格
tableSelection: [], // 表格已选中
};
},
filters: {
tableDataFilter(value) {
return value.map((item, index) => ({ ...item, $index: index }));
},
},
methods: {
onHeaderClick() {
this.tableEditCell = {};
},
onCellClick(row, column, cell, event) {
if (row.$index !== this.tableEditCell.index || column.property !== this.tableEditCell.prop) {
this.tableEditCell = {};
}
},
onCellDblclick(row, column, cell, event) {
this.tableEditCell = { index: row.$index, prop: column.property };
},
onCellInput(value) {
const tableData = cloneDeep(this.tableData);
const tableRow = tableData[this.tableEditCell.index];
set(tableRow, this.tableEditCell.prop, value);
tableData[this.tableEditCell.index] = tableRow;
this.$set(this.tableData, this.tableEditCell.index, tableRow);
},
},
};
</script>