Commit 984d820ea9f54e084efcac66c20261827cf41edd

Authored by Aaron
1 parent d22cb190
Exists in master and in 1 other branch legacy

新式表格支持行内编辑

examples/views/page/other.vue
@@ -76,7 +76,7 @@ export default { @@ -76,7 +76,7 @@ export default {
76 // { type: 'el-input', label: '市', key: 'city', render: { type: 'el-tag', props: { type: 'danger', size: 'mini' } } }, 76 // { type: 'el-input', label: '市', key: 'city', render: { type: 'el-tag', props: { type: 'danger', size: 'mini' } } },
77 { type: 'el-input', label: '市', key: 'city', 77 { type: 'el-input', label: '市', key: 'city',
78 render: { 78 render: {
79 - type: 'span', props: { href: 'https:///www.baidu.com/' }, style: { color: 'red' }, 79 + type: 'a', props: { href: 'https:///www.baidu.com/', target: '_blank' }, style: { color: 'red' },
80 children({ row }) { 80 children({ row }) {
81 const { location: { district: { city } = {} } = {} } = row; 81 const { location: { district: { city } = {} } = {} } = row;
82 return city ? `${city}[城市]` : ''; 82 return city ? `${city}[城市]` : '';
examples/views/page/table-new/index.vue
@@ -2,49 +2,93 @@ @@ -2,49 +2,93 @@
2 .eagle-table { 2 .eagle-table {
3 width: 100%; 3 width: 100%;
4 } 4 }
  5 +.eagle-table-cell-edit {
  6 + display: flex;
  7 + align-items: center;
  8 +}
5 </style> 9 </style>
6 10
7 <template> 11 <template>
8 - <div> 12 + <div @keyup.enter="editCell = {}">
9 <pre>{{ tableList }}</pre> 13 <pre>{{ tableList }}</pre>
10 - <el-table class="eagle-table" ref="table" :data="tableData" v-bind="{ size: 'small', ...tableProps }" v-on="tableEvents"> 14 + <el-table class="eagle-table" ref="table" :data="tableData" v-bind="{ size: 'small', ...tableProps }" v-on="tableEvents" @cell-dblclick="onCellDblclick">
  15 + <!-- 默认表格插槽 -->
11 <slot name="default"></slot> 16 <slot name="default"></slot>
  17 + <!-- 根据配置列表生成表格列 -->
12 <template v-if="tableList && tableList.length > 0"> 18 <template v-if="tableList && tableList.length > 0">
13 <template v-for="(item, index) in tableList"> 19 <template v-for="(item, index) in tableList">
14 <template v-if="bindItemVisible(item.visible)"> 20 <template v-if="bindItemVisible(item.visible)">
  21 + <!-- 如果有表格列具名插槽 -->
15 <slot v-if="$scopedSlots[item.keyPath.join('-')] || $slots[item.keyPath.join('-')]" :name="item.keyPath.join('-')" v-bind="item"></slot> 22 <slot v-if="$scopedSlots[item.keyPath.join('-')] || $slots[item.keyPath.join('-')]" :name="item.keyPath.join('-')" v-bind="item"></slot>
  23 + <!-- 如果有表格列值渲染具名插槽 -->
16 <el-table-column v-else-if="$scopedSlots[`value-${item.keyPath.join('-')}`] || $slots[`value-${item.keyPath.join('-')}`]" 24 <el-table-column v-else-if="$scopedSlots[`value-${item.keyPath.join('-')}`] || $slots[`value-${item.keyPath.join('-')}`]"
17 v-bind="item" :prop="item.agentKey || item.fullKey || item.key" :key="index" 25 v-bind="item" :prop="item.agentKey || item.fullKey || item.key" :key="index"
18 :min-width="item.minWidth || item['min-width']" 26 :min-width="item.minWidth || item['min-width']"
19 > 27 >
20 - <slot slot-scope="{ row, column, $index }" :name="`value-${item.keyPath.join('-')}`" v-bind="item"  
21 - :row="row" :value="$_get(row, item.fullKey)" :column="column" :index="$index"  
22 - ></slot> 28 + <template slot-scope="{ row, column, $index }">
  29 + <div v-if="editCell.index === row.$index && editCell.key === (item.agentKey || item.fullKey || item.key)" class="eagle-table-cell-edit">
  30 + <component
  31 + :value="$_get(row, item.fullKey)"
  32 + :is="item.type" v-bind="item.props" :style="item.style" size="mini"
  33 + @input="v => onCellUpdate({ value: v, row, key: item.fullKey })"
  34 + ></component>
  35 + <el-button type="text" icon="el-icon-check" @click="editCell = {}"></el-button>
  36 + </div>
  37 + <slot v-else :name="`value-${item.keyPath.join('-')}`" v-bind="item"
  38 + :row="row" :value="$_get(row, item.fullKey)" :column="column" :index="$index"
  39 + ></slot>
  40 + </template>
23 </el-table-column> 41 </el-table-column>
  42 + <!-- 如果表格列配置了值渲染参数 -->
24 <el-table-column v-else-if="item.render" v-bind="item" :prop="item.agentKey || item.fullKey || item.key" 43 <el-table-column v-else-if="item.render" v-bind="item" :prop="item.agentKey || item.fullKey || item.key"
25 :key="index" :min-width="item.minWidth || item['min-width']" 44 :key="index" :min-width="item.minWidth || item['min-width']"
26 > 45 >
27 - <template slot-scope="slotScope">  
28 - <component :is="item.render.type" v-bind="item.render.props" :style="item.render.style">  
29 - <template v-if="item.render.children">{{ bindItemRenderChildren(item, slotScope) }}</template>  
30 - <template v-else>{{ $_get(row, item.fullKey) }}</template>  
31 - </component> 46 + <template slot-scope="{ row, column, $index }">
  47 + <div v-if="editCell.index === row.$index && editCell.key === (item.agentKey || item.fullKey || item.key)" class="eagle-table-cell-edit">
  48 + <component
  49 + :value="$_get(row, item.fullKey)"
  50 + :is="item.type" v-bind="item.props" :style="item.style" size="mini"
  51 + @input="v => onCellUpdate({ value: v, row, key: item.fullKey })"
  52 + ></component>
  53 + <el-button type="text" icon="el-icon-check" @click="editCell = {}"></el-button>
  54 + </div>
  55 + <template v-else>
  56 + <component :is="item.render.type" v-bind="item.render.props" :style="item.render.style">
  57 + <template v-if="item.render.children">{{ bindItemRenderChildren(item, { row, column, $index }) }}</template>
  58 + <template v-else>{{ $_get(row, item.fullKey) }}</template>
  59 + </component>
  60 + </template>
32 </template> 61 </template>
33 </el-table-column> 62 </el-table-column>
  63 + <!-- 默认表格列渲染 -->
34 <el-table-column v-else v-bind="item" :prop="item.agentKey || item.fullKey || item.key" 64 <el-table-column v-else v-bind="item" :prop="item.agentKey || item.fullKey || item.key"
35 - :key="index" :min-width="item.minWidth || item['min-width']"  
36 - ></el-table-column> 65 + :key="index" :min-width="item.minWidth || item['min-width'] || 120"
  66 + >
  67 + <template slot-scope="{ row }">
  68 + <div v-if="editCell.index === row.$index && editCell.key === (item.agentKey || item.fullKey || item.key)" class="eagle-table-cell-edit">
  69 + <component
  70 + :value="$_get(row, item.fullKey)"
  71 + :is="item.type" v-bind="item.props" :style="item.style" size="mini"
  72 + @input="v => onCellUpdate({ value: v, row, key: item.fullKey })"
  73 + ></component>
  74 + <el-button type="text" icon="el-icon-check" @click="editCell = {}"></el-button>
  75 + </div>
  76 + <template v-else>{{ $_get(row, item.fullKey) }}</template>
  77 + </template>
  78 + </el-table-column>
37 </template> 79 </template>
38 </template> 80 </template>
39 </template> 81 </template>
  82 + <!-- 已生成列表后的追加列插槽 -->
40 <slot name="column-append"></slot> 83 <slot name="column-append"></slot>
  84 + <!-- 末尾列插槽 -->
41 <slot name="column-end"></slot> 85 <slot name="column-end"></slot>
42 </el-table> 86 </el-table>
43 </div> 87 </div>
44 </template> 88 </template>
45 89
46 <script> 90 <script>
47 -import { cloneDeep, get } from '../form-new/util'; 91 +import { cloneDeep, get, set } from '../form-new/util';
48 92
49 export default { 93 export default {
50 name: 'TableNew', 94 name: 'TableNew',
@@ -68,6 +112,7 @@ export default { @@ -68,6 +112,7 @@ export default {
68 return { 112 return {
69 tableList: [], 113 tableList: [],
70 tableData: [], 114 tableData: [],
  115 + editCell: {},
71 }; 116 };
72 }, 117 },
73 computed: { 118 computed: {
@@ -81,7 +126,7 @@ export default { @@ -81,7 +126,7 @@ export default {
81 watch: { 126 watch: {
82 value: { 127 value: {
83 handler(val = []) { 128 handler(val = []) {
84 - this.tableData = val; 129 + this.tableData = val.map((o, i) => ({ ...o, $index: i }));
85 }, 130 },
86 immediate: true 131 immediate: true
87 }, 132 },
@@ -137,6 +182,20 @@ export default { @@ -137,6 +182,20 @@ export default {
137 // 处理表格项渲染时的子值 182 // 处理表格项渲染时的子值
138 bindItemRenderChildren(item, scope) { 183 bindItemRenderChildren(item, scope) {
139 return item.render.children instanceof Function ? item.render.children(scope) : this.$_get(scope.row, item.fullKey) 184 return item.render.children instanceof Function ? item.render.children(scope) : this.$_get(scope.row, item.fullKey)
  185 + },
  186 + // 双击单元格
  187 + onCellDblclick(row, column, cell, event) {
  188 + this.editCell = { index: row.$index, key: column.property };
  189 + },
  190 + // 编辑表格更新值
  191 + onCellUpdate({ value, row, key }) {
  192 + const tableData = cloneDeep(this.tableData);
  193 + const tableRow = tableData[row.$index];
  194 + set(tableRow, key, value);
  195 + tableData[row.$index] = tableRow;
  196 + this.$set(this.tableData, row.$index, tableRow);
  197 + // this.tableData = tableData;
  198 + // this.$emit('input', tableData);
140 } 199 }
141 } 200 }
142 }; 201 };
packages/scheme/index.vue
@@ -138,7 +138,7 @@ @@ -138,7 +138,7 @@
138 ...tableEvents, 138 ...tableEvents,
139 }" 139 }"
140 > 140 >
141 - <slot></slot> 141 + <slot v-bind="slotMethod"></slot>
142 <!-- 表格具名插槽 --> 142 <!-- 表格具名插槽 -->
143 <template v-for="(item, index) in tableList || _tableList"> 143 <template v-for="(item, index) in tableList || _tableList">
144 <slot v-if="$scopedSlots[`table-${item.key}`] || $slots[`table-${item.key}`]" :name="`table-${item.key}`" :slot="item.key" v-bind="slotMethod"></slot> 144 <slot v-if="$scopedSlots[`table-${item.key}`] || $slots[`table-${item.key}`]" :name="`table-${item.key}`" :slot="item.key" v-bind="slotMethod"></slot>