Commit 841b3ab4a065635ac2c043a4cba46195eaa2fb26
1 parent
984d820e
Exists in
master
and in
1 other branch
优化新式表格可编辑渲染
Showing
3 changed files
with
88 additions
and
65 deletions
Show diff stats
examples/views/page/other.vue
| ... | ... | @@ -13,13 +13,13 @@ |
| 13 | 13 | <template> |
| 14 | 14 | <div> |
| 15 | 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 | 17 | <el-table-column type="selection"></el-table-column> |
| 18 | 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 | 20 | </template> |
| 21 | 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 | 23 | </template> |
| 24 | 24 | <!-- <template #location-district-city> |
| 25 | 25 | <el-table-column label="城市测试" prop="location-district-city"> |
| ... | ... | @@ -47,6 +47,7 @@ export default { |
| 47 | 47 | components: { EgForm, EgTable }, |
| 48 | 48 | data() { |
| 49 | 49 | return { |
| 50 | + tableData: [], | |
| 50 | 51 | model: { |
| 51 | 52 | name: 'name', |
| 52 | 53 | location: { |
| ... | ... | @@ -72,7 +73,7 @@ export default { |
| 72 | 73 | { |
| 73 | 74 | group: { key: 'district' }, |
| 74 | 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 | 77 | // { type: 'el-input', label: '市', key: 'city', render: { type: 'el-tag', props: { type: 'danger', size: 'mini' } } }, |
| 77 | 78 | { type: 'el-input', label: '市', key: 'city', |
| 78 | 79 | render: { |
| ... | ... | @@ -151,7 +152,8 @@ export default { |
| 151 | 152 | height: '3', |
| 152 | 153 | weight: '4' |
| 153 | 154 | } |
| 154 | - }, 3000); | |
| 155 | + this.tableData = [this.model]; | |
| 156 | + }, 1000); | |
| 155 | 157 | }, |
| 156 | 158 | methods: { |
| 157 | 159 | onValidate(isValidated, model) { | ... | ... |
| ... | ... | @@ -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 | 58 | \ No newline at end of file | ... | ... |
examples/views/page/table-new/index.vue
| ... | ... | @@ -2,15 +2,10 @@ |
| 2 | 2 | .eagle-table { |
| 3 | 3 | width: 100%; |
| 4 | 4 | } |
| 5 | -.eagle-table-cell-edit { | |
| 6 | - display: flex; | |
| 7 | - align-items: center; | |
| 8 | -} | |
| 9 | 5 | </style> |
| 10 | 6 | |
| 11 | 7 | <template> |
| 12 | 8 | <div @keyup.enter="editCell = {}"> |
| 13 | - <pre>{{ tableList }}</pre> | |
| 14 | 9 | <el-table class="eagle-table" ref="table" :data="tableData" v-bind="{ size: 'small', ...tableProps }" v-on="tableEvents" @cell-dblclick="onCellDblclick"> |
| 15 | 10 | <!-- 默认表格插槽 --> |
| 16 | 11 | <slot name="default"></slot> |
| ... | ... | @@ -19,61 +14,24 @@ |
| 19 | 14 | <template v-for="(item, index) in tableList"> |
| 20 | 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 | 31 | <template v-if="item.render.children">{{ bindItemRenderChildren(item, { row, column, $index }) }}</template> |
| 58 | 32 | <template v-else>{{ $_get(row, item.fullKey) }}</template> |
| 59 | 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 | 35 | </template> |
| 78 | 36 | </el-table-column> |
| 79 | 37 | </template> |
| ... | ... | @@ -89,9 +47,11 @@ |
| 89 | 47 | |
| 90 | 48 | <script> |
| 91 | 49 | import { cloneDeep, get, set } from '../form-new/util'; |
| 50 | +import CellEditable from './cell-editable'; | |
| 92 | 51 | |
| 93 | 52 | export default { |
| 94 | 53 | name: 'TableNew', |
| 54 | + components: { CellEditable }, | |
| 95 | 55 | props: { |
| 96 | 56 | // 用于实例化本组件绑定v-model的值 |
| 97 | 57 | value: Array, |
| ... | ... | @@ -107,6 +67,8 @@ export default { |
| 107 | 67 | }, |
| 108 | 68 | // 表格事件 |
| 109 | 69 | tableEvents: Object, |
| 70 | + // 是否可编辑 | |
| 71 | + editable: Boolean, | |
| 110 | 72 | }, |
| 111 | 73 | data() { |
| 112 | 74 | return { |
| ... | ... | @@ -193,9 +155,11 @@ export default { |
| 193 | 155 | const tableRow = tableData[row.$index]; |
| 194 | 156 | set(tableRow, key, value); |
| 195 | 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 | }; | ... | ... |