Commit 841b3ab4a065635ac2c043a4cba46195eaa2fb26

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

优化新式表格可编辑渲染

examples/views/page/other.vue
@@ -13,13 +13,13 @@ @@ -13,13 +13,13 @@
13 <template> 13 <template>
14 <div> 14 <div>
15 <pre>{{ model }}</pre> 15 <pre>{{ model }}</pre>
16 - <eg-table :value="[this.model]" :list="option.list" :tableProps="{ border: true }"> 16 + <eg-table v-model="tableData" :list="option.list" :tableProps="{ border: true }" editable>
17 <el-table-column type="selection"></el-table-column> 17 <el-table-column type="selection"></el-table-column>
18 <template #value-location-locationMin="{ value }"> 18 <template #value-location-locationMin="{ value }">
19 - <el-tag size="mini">{{ value }}</el-tag> 19 + <el-tag v-if="value" size="mini" disable-transitions>{{ value }}</el-tag>
20 </template> 20 </template>
21 <template #value-location-district-province="{ value }"> 21 <template #value-location-district-province="{ value }">
22 - <el-tag type="success" size="mini">{{ value }}</el-tag> 22 + <el-tag v-if="value" type="success" size="mini" disable-transitions>{{ value }}</el-tag>
23 </template> 23 </template>
24 <!-- <template #location-district-city> 24 <!-- <template #location-district-city>
25 <el-table-column label="城市测试" prop="location-district-city"> 25 <el-table-column label="城市测试" prop="location-district-city">
@@ -47,6 +47,7 @@ export default { @@ -47,6 +47,7 @@ export default {
47 components: { EgForm, EgTable }, 47 components: { EgForm, EgTable },
48 data() { 48 data() {
49 return { 49 return {
  50 + tableData: [],
50 model: { 51 model: {
51 name: 'name', 52 name: 'name',
52 location: { 53 location: {
@@ -72,7 +73,7 @@ export default { @@ -72,7 +73,7 @@ export default {
72 { 73 {
73 group: { key: 'district' }, 74 group: { key: 'district' },
74 list: [ 75 list: [
75 - { type: 'el-input', label: '省', key: 'province', rules: [{ required: true, message: '请输入省' }] }, 76 + { type: 'eagle-select', label: '省', key: 'province', props: { dataSource: [{ label: '上海', value: '上海' }, { label: '北京', value: '北京' }] }, rules: [{ required: true, message: '请输入省', trigger: 'change' }], minWidth: 120 },
76 // { type: 'el-input', label: '市', key: 'city', render: { type: 'el-tag', props: { type: 'danger', size: 'mini' } } }, 77 // { type: 'el-input', label: '市', key: 'city', render: { type: 'el-tag', props: { type: 'danger', size: 'mini' } } },
77 { type: 'el-input', label: '市', key: 'city', 78 { type: 'el-input', label: '市', key: 'city',
78 render: { 79 render: {
@@ -151,7 +152,8 @@ export default { @@ -151,7 +152,8 @@ export default {
151 height: '3', 152 height: '3',
152 weight: '4' 153 weight: '4'
153 } 154 }
154 - }, 3000); 155 + this.tableData = [this.model];
  156 + }, 1000);
155 }, 157 },
156 methods: { 158 methods: {
157 onValidate(isValidated, model) { 159 onValidate(isValidated, model) {
examples/views/page/table-new/cell-editable.vue 0 → 100644
@@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
  1 +<style>
  2 +.eagle-table-cell-editable {
  3 + display: flex;
  4 + align-items: center;
  5 +}
  6 +.eagle-table-cell-editable .eagle-table-cell-editable__icon {
  7 + cursor: pointer;
  8 + vertical-align: middle;
  9 + padding-left: 5px;
  10 + fill: #2f54eb;
  11 +}
  12 +</style>
  13 +
  14 +<template>
  15 + <div>
  16 + <!-- 可编辑状态 -->
  17 + <div v-if="editable" class="eagle-table-cell-editable">
  18 + <component
  19 + :value="$_get(row, item.fullKey)"
  20 + :is="item.type" v-bind="item.props" :style="item.style" size="mini"
  21 + @input="v => $emit('update', { value: v, row, key: item.fullKey })"
  22 + ></component>
  23 + <span @click="$emit('done')">
  24 + <svg class="eagle-table-cell-editable__icon" viewBox="0 0 1024 1024" width="24" height="24">
  25 + <path d="M235.946667 472.938667l-45.226667 45.312 210.090667 209.514666 432.362666-427.690666-45.013333-45.482667-387.157333 382.976z"></path>
  26 + </svg>
  27 + </span>
  28 + </div>
  29 + <!-- 渲染状态 -->
  30 + <template v-else>
  31 + <!-- 渲染插槽 -->
  32 + <template v-if="$scopedSlots['default']">
  33 + <slot></slot>
  34 + </template>
  35 + <!-- 默认渲染 -->
  36 + <template v-else>
  37 + {{ $_get(row, item.agentKey || item.fullKey) }}
  38 + </template>
  39 + </template>
  40 + </div>
  41 +</template>
  42 +
  43 +<script>
  44 +import { get } from '../form-new/util';
  45 +
  46 +export default {
  47 + name: 'cellEditable',
  48 + props: {
  49 + row: Object,
  50 + item: Object,
  51 + editable: Boolean,
  52 + },
  53 + methods: {
  54 + $_get: get,
  55 + }
  56 +}
  57 +</script>
0 \ No newline at end of file 58 \ No newline at end of file
examples/views/page/table-new/index.vue
@@ -2,15 +2,10 @@ @@ -2,15 +2,10 @@
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 -}  
9 </style> 5 </style>
10 6
11 <template> 7 <template>
12 <div @keyup.enter="editCell = {}"> 8 <div @keyup.enter="editCell = {}">
13 - <pre>{{ tableList }}</pre>  
14 <el-table class="eagle-table" ref="table" :data="tableData" v-bind="{ size: 'small', ...tableProps }" v-on="tableEvents" @cell-dblclick="onCellDblclick"> 9 <el-table class="eagle-table" ref="table" :data="tableData" v-bind="{ size: 'small', ...tableProps }" v-on="tableEvents" @cell-dblclick="onCellDblclick">
15 <!-- 默认表格插槽 --> 10 <!-- 默认表格插槽 -->
16 <slot name="default"></slot> 11 <slot name="default"></slot>
@@ -19,61 +14,24 @@ @@ -19,61 +14,24 @@
19 <template v-for="(item, index) in tableList"> 14 <template v-for="(item, index) in tableList">
20 <template v-if="bindItemVisible(item.visible)"> 15 <template v-if="bindItemVisible(item.visible)">
21 <!-- 如果有表格列具名插槽 --> 16 <!-- 如果有表格列具名插槽 -->
22 - <slot v-if="$scopedSlots[item.keyPath.join('-')] || $slots[item.keyPath.join('-')]" :name="item.keyPath.join('-')" v-bind="item"></slot>  
23 - <!-- 如果有表格列值渲染具名插槽 -->  
24 - <el-table-column v-else-if="$scopedSlots[`value-${item.keyPath.join('-')}`] || $slots[`value-${item.keyPath.join('-')}`]"  
25 - v-bind="item" :prop="item.agentKey || item.fullKey || item.key" :key="index"  
26 - :min-width="item.minWidth || item['min-width']"  
27 - >  
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>  
41 - </el-table-column>  
42 - <!-- 如果表格列配置了值渲染参数 -->  
43 - <el-table-column v-else-if="item.render" v-bind="item" :prop="item.agentKey || item.fullKey || item.key"  
44 - :key="index" :min-width="item.minWidth || item['min-width']"  
45 - >  
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"> 17 + <slot v-if="$scopedSlots[item.keyPath.join('-')]" :name="item.keyPath.join('-')" v-bind="item"></slot>
  18 + <!-- 默认表格列渲染 -->
  19 + <el-table-column v-else v-bind="item" :prop="item.agentKey || item.fullKey || item.key" :key="index" :min-width="item.minWidth || item['min-width'] || 140">
  20 + <template #default="{ row, column, $index }">
  21 + <cell-editable
  22 + :editable="editable && (editCell.index === row.$index && editCell.key === (item.agentKey || item.fullKey || item.key))"
  23 + :row="row" :item="item" @update="onCellUpdate" @done="editCell = {}"
  24 + >
  25 + <!-- 如果有表格列值渲染具名插槽 -->
  26 + <slot v-if="$scopedSlots[`value-${item.keyPath.join('-')}`]" :name="`value-${item.keyPath.join('-')}`" v-bind="item"
  27 + :row="row" :value="$_get(row, item.fullKey)" :column="column" :index="$index"
  28 + ></slot>
  29 + <!-- 如果表格列配置了值渲染参数 -->
  30 + <component v-else-if="item.render" :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> 31 <template v-if="item.render.children">{{ bindItemRenderChildren(item, { row, column, $index }) }}</template>
58 <template v-else>{{ $_get(row, item.fullKey) }}</template> 32 <template v-else>{{ $_get(row, item.fullKey) }}</template>
59 </component> 33 </component>
60 - </template>  
61 - </template>  
62 - </el-table-column>  
63 - <!-- 默认表格列渲染 -->  
64 - <el-table-column v-else v-bind="item" :prop="item.agentKey || item.fullKey || item.key"  
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> 34 + </cell-editable>
77 </template> 35 </template>
78 </el-table-column> 36 </el-table-column>
79 </template> 37 </template>
@@ -89,9 +47,11 @@ @@ -89,9 +47,11 @@
89 47
90 <script> 48 <script>
91 import { cloneDeep, get, set } from '../form-new/util'; 49 import { cloneDeep, get, set } from '../form-new/util';
  50 +import CellEditable from './cell-editable';
92 51
93 export default { 52 export default {
94 name: 'TableNew', 53 name: 'TableNew',
  54 + components: { CellEditable },
95 props: { 55 props: {
96 // 用于实例化本组件绑定v-model的值 56 // 用于实例化本组件绑定v-model的值
97 value: Array, 57 value: Array,
@@ -107,6 +67,8 @@ export default { @@ -107,6 +67,8 @@ export default {
107 }, 67 },
108 // 表格事件 68 // 表格事件
109 tableEvents: Object, 69 tableEvents: Object,
  70 + // 是否可编辑
  71 + editable: Boolean,
110 }, 72 },
111 data() { 73 data() {
112 return { 74 return {
@@ -193,9 +155,11 @@ export default { @@ -193,9 +155,11 @@ export default {
193 const tableRow = tableData[row.$index]; 155 const tableRow = tableData[row.$index];
194 set(tableRow, key, value); 156 set(tableRow, key, value);
195 tableData[row.$index] = tableRow; 157 tableData[row.$index] = tableRow;
196 - this.$set(this.tableData, row.$index, tableRow);  
197 - // this.tableData = tableData;  
198 - // this.$emit('input', tableData); 158 + if (this.$listeners['input']) {
  159 + this.$emit('input', tableData);
  160 + } else {
  161 + this.$set(this.tableData, row.$index, tableRow);
  162 + }
199 } 163 }
200 } 164 }
201 }; 165 };