优雅的elementUI table 单元格可编辑实现方法

84次阅读

共计 6878 个字符,预计需要花费 18 分钟才能阅读完成。

最近在做可编辑特定列的单元格的 elementUI table,看了 N 多的开源、文章,找到一个很优雅的实现方式,分享给大家。PS: 单元格可编辑的 table,用英文搜索:Inline editable table with ElementUI 会得到高质量结果。
先上效果:
APP.vue:
<template>
<div id=”app”>
<div style=”margin-bottom: 30px”>
<el-switch
style=”display: block”
v-model=”editModeEnabled”
active-color=”#13ce66″
inactive-color=”#ff4949″
active-text=”Edit enabled”
inactive-text=”Edit disabled”>
</el-switch>
</div>
<el-table
:data=”gridData”
style=”width: 100%”>
<el-table-column
label=”Name”
min-width=”180″>
<editable-cell slot-scope=”{row}”
:can-edit=”editModeEnabled”
v-model=”row.name”>
<span slot=”content”>{{row.name}}</span>
</editable-cell>
</el-table-column>

<el-table-column
min-wwidth=”150″
label=”Gender”>

<editable-cell
slot-scope=”{row}”
editable-component=”el-select”
:can-edit=”editModeEnabled”
close-event=”change”
v-model=”row.gender”>

<el-tag size=”medium”
:type=”row.gender === ‘M’ ? ‘primary’ : ‘danger'”
slot=”content”>
{{row.gender === ‘M’ ? ‘Male’: ‘Female’}}
</el-tag>

<template slot=”edit-component-slot”>
<el-option value=”M” label=”Male”></el-option>
<el-option value=”F” label=”Female”></el-option>
</template>
</editable-cell>

</el-table-column>

<el-table-column
label=”Birth Date”
min-width=”250″>
<editable-cell
slot-scope=”{row}”
:can-edit=”editModeEnabled”
editable-component=”el-date-picker”
format=”yyyy-MM-dd”
value-format=”yyyy-MM-dd”
v-model=”row.date”>
<span slot=”content”>{{row.date}}</span>
</editable-cell>
</el-table-column>
</el-table>
</div>
</template>

<script>
import EditableCell from “./components/EditableCell.vue”;

export default {
name: “App”,
components: {
EditableCell
},
data() {
return {
editModeEnabled: false,
gridData: [
{
date: “2016-05-03”,
name: “Tom”,
gender: “M”
},
{
date: “2016-05-02”,
name: “Lisa”,
gender: “F”
},
{
date: “2016-05-04”,
name: “Jon”,
gender: “M”
},
{
date: “2016-05-01”,
name: “Mary”,
gender: “F”
}
]
};
}
};
</script>

<style>
.edit-cell {
min-height: 35px;
cursor: pointer;
}
</style>

EditeableCell.vue:
<template>
<div @click=”onFieldClick” class=”edit-cell”>
<el-tooltip v-if=”!editMode && !showInput”
:placement=”toolTipPlacement”
:open-delay=”toolTipDelay”
:content=”toolTipContent”>
<div tabindex=”0″
class=”cell-content”
:class=”{‘edit-enabled-cell’: canEdit}”
@keyup.enter=”onFieldClick”>
<slot name=”content”></slot>
</div>

</el-tooltip>
<component :is=”editableComponent”
v-if=”editMode || showInput”
ref=”input”
@focus=”onFieldClick”
@keyup.enter.native=”onInputExit”
v-on=”listeners”
v-bind=”$attrs”
v-model=”model”>
<slot name=”edit-component-slot”></slot>
</component>
</div>
</template>
<script>
export default {
name: “editable-cell”,
inheritAttrs: false,
props: {
value: {
type: String,
default: “”
},
toolTipContent: {
type: String,
default: “Click to edit”
},
toolTipDelay: {
type: Number,
default: 500
},
toolTipPlacement: {
type: String,
default: “top-start”
},
showInput: {
type: Boolean,
default: false
},
editableComponent: {
type: String,
default: “el-input”
},
closeEvent: {
type: String,
default: “blur”
},
canEdit: {
type: Boolean,
default: false
}
},
data() {
return {
editMode: false
};
},
computed: {
model: {
get() {
return this.value;
},
set(val) {
this.$emit(“input”, val);
}
},
listeners() {
return {
[this.closeEvent]: this.onInputExit,
…this.$listeners
};
}
},
methods: {
onFieldClick() {
if (this.canEdit) {
this.editMode = true;
this.$nextTick(() => {
let inputRef = this.$refs.input;
if (inputRef && inputRef.focus) {
inputRef.focus();
}
});
}
},
onInputExit() {
this.editMode = false;
},
onInputChange(val) {
this.$emit(“input”, val);
}
}
};
</script>
<style>
.cell-content {
min-height: 40px;
padding-left: 5px;
padding-top: 5px;
border: 1px solid transparent;
}
.edit-enabled-cell {
border: 1px dashed #409eff;
}
</style>

在线查看(可能需要科学上网):https://codesandbox.io/s/2pv1…github:https://github.com/heianxing/…
另外一个单元格编辑的例子:
App.vue:
<template>
<div id=”app”>
<el-tooltip content=”Click on any of the cells or on the edit button to edit content”>
<i class=”el-icon-info”></i>
</el-tooltip>
<el-table
:data=”gridData”
style=”width: 100%”>

<el-table-column
label=”Operations”
min-width=”180″>
<template slot-scope=”{row, index}”>
<el-button icon=”el-icon-edit”
@click=”setEditMode(row, index)”>
</el-button>
<el-button type=”success” icon=”el-icon-check”
@click=”saveRow(row, index)”>
</el-button>
</template>
</el-table-column>

<el-table-column
label=”Name”
min-width=”180″>
<editable-cell :show-input=”row.editMode” slot-scope=”{row}” v-model=”row.name”>
<span slot=”content”>{{row.name}}</span>
</editable-cell>
</el-table-column>

<el-table-column
min-wwidth=”150″
label=”Gender”>

<editable-cell
:show-input=”row.editMode”
slot-scope=”{row}”
editable-component=”el-select”
close-event=”change”
v-model=”row.gender”>

<el-tag size=”medium”
:type=”row.gender === ‘M’ ? ‘primary’ : ‘danger'”
slot=”content”>
{{row.gender === ‘M’ ? ‘Male’: ‘Female’}}
</el-tag>

<template slot=”edit-component-slot”>
<el-option value=”M” label=”Male”></el-option>
<el-option value=”F” label=”Female”></el-option>
</template>
</editable-cell>

</el-table-column>

<el-table-column
label=”Birth Date”
min-width=”250″>
<editable-cell
:show-input=”row.editMode”
slot-scope=”{row}”
editable-component=”el-date-picker”
format=”yyyy-MM-dd”
value-format=”yyyy-MM-dd”
v-model=”row.date”>
<span slot=”content”>{{row.date}}</span>
</editable-cell>
</el-table-column>
</el-table>
</div>
</template>

<script>
import EditableCell from “./components/EditableCell.vue”;

export default {
name: “App”,
components: {
EditableCell
},
data() {
return {
gridData: [
{
date: “2016-05-03”,
name: “Tom”,
gender: “M”
},
{
date: “2016-05-02”,
name: “Lisa”,
gender: “F”
},
{
date: “2016-05-04”,
name: “Jon”,
gender: “M”
},
{
date: “2016-05-01”,
name: “Mary”,
gender: “F”
}
]
};
},
methods: {
setEditMode(row, index) {
row.editMode = true;
},
saveRow(row, index) {
row.editMode = false;
}
},
mounted() {
this.gridData = this.gridData.map(row => {
return {
…row,
editMode: false
};
});
}
};
</script>

<style>
.edit-cell {
min-height: 35px;
cursor: pointer;
}
</style>

EditeableCell.vue:
<template>
<div @click=”onFieldClick” class=”edit-cell”>
<el-tooltip v-if=”!editMode && !showInput”
:placement=”toolTipPlacement”
:open-delay=”toolTipDelay”
:content=”toolTipContent”>
<div tabindex=”0″ @keyup.enter=”onFieldClick”>
<slot name=”content”></slot>
</div>

</el-tooltip>
<component :is=”editableComponent”
v-if=”editMode || showInput”
ref=”input”
@focus=”onFieldClick”
@keyup.enter.native=”onInputExit”
v-on=”listeners”
v-bind=”$attrs”
v-model=”model”>
<slot name=”edit-component-slot”></slot>
</component>
</div>
</template>
<script>
export default {
name: “editable-cell”,
inheritAttrs: false,
props: {
value: {
type: String,
default: “”
},
toolTipContent: {
type: String,
default: “Click to edit”
},
toolTipDelay: {
type: Number,
default: 500
},
toolTipPlacement: {
type: String,
default: “top-start”
},
showInput: {
type: Boolean,
default: false
},
editableComponent: {
type: String,
default: “el-input”
},
closeEvent: {
type: String,
default: “blur”
}
},
data() {
return {
editMode: false
};
},
computed: {
model: {
get() {
return this.value;
},
set(val) {
this.$emit(“input”, val);
}
},
listeners() {
return {
[this.closeEvent]: this.onInputExit,
…this.$listeners
};
}
},
methods: {
onFieldClick() {
this.editMode = true;
this.$nextTick(() => {
let inputRef = this.$refs.input;
if (inputRef) {
inputRef.focus();
}
});
},
onInputExit() {
this.editMode = false;
},
onInputChange(val) {
this.$emit(“input”, val);
}
}
};
</script>
<style>

</style>

在线查看(可能需要科学上网):https://codesandbox.io/s/mrqq…github:https://github.com/heianxing/…
英文来源:https://www.reddit.com/r/vuej…

正文完
 0