antd + vue 点击编辑文本切换成可编辑状态(附下拉框)
最近写任务的时候遇到这样一个前端功能:
默认展示文本和编辑图标,点击删除之后,文本的位置切换成输入框,如下所示:
点击编辑图标之后
我参照了的antd文档中table组件的一个可编辑单元格的例子,单独写一个组件,让它在内部控制自己的可编辑状态。
组件:
<div v-if="editable" class="editable-cell-input-wrapper"> <a-input v-model="value" @pressEnter="check" /> <a class="c-theme" type="primary" @click="check">保存</a> <a class="c-theme" @click="onCancel">取消</a> </div> <div v-else class="editable-cell-text-wrapper"> {{ value || " " }} <a-icon type="edit" theme="twoTone" :style="{ fontSize: '18px' }" class="editable-cell-icon" @click="edit" /> </div>
data内部的数据
data() { return { value: "", editable: false, preValue: "" }; },
控制事件
// 取消 onCancel() { this.value = this.preValue; this.editable = false; }, // 保存 check() { this.editable = false; } // 点击编辑 edit() { this.preValue = this.value; this.editable = true; }
这就完成了,但是后面又要求加一个选择下拉框,再点击“编辑”图标时,输入框跟下拉框一起显示出来,点击“保存”或者“取消”时作相应处理,并切换成新的文本显示。
我一开始是直接把下拉框加在外部组件里面的,结果控制它的可见状态十分麻烦,所以干脆把它也加在之前的组件里,让下拉框和输入框组成一个单独的组件,同样用editable控制文本和编辑态的切换:
组件
<template> <div class="editable-cell"> <div class="editable-cell-select-text-wrapper" v-if="!editable" > {{ selectedTitle}} </div> <div class="editable-cell-select-wrapper" v-if="editable"> <a-select v-model="selectedLan"> <a-select-option :value="option.language" v-for="(option, index) in languages" :key="index" > {{ languages.length > 0 ? option.title : "" }} </a-select-option> </a-select> </div> <div v-if="editable" class="editable-cell-input-wrapper"> <a-input v-model="value" @pressEnter="check" /> <a class="c-theme" type="primary" @click="check">保存</a> <a class="c-theme" @click="onCancel">取消</a> </div> <div v-else class="editable-cell-text-wrapper"> {{ value || " " }} <a-icon type="edit" theme="twoTone" :style="{ fontSize: '18px' }" class="editable-cell-icon" @click="edit" /> </div> </div> </template>
data
data() { return { selectedLan: "", value: "", editable: false, preValue: "", preSelected: "", languages: [ {language: 'zh', title: '中文'}, {language: 'en', title: '英文'}, {language: 'ja', title: '日文'} ] }; },
方法
check() {
this.editable = false;
}
},
onCancel() {
this.value = this.preValue;
this.selectedLan = this.preSelected;
this.editable = false;
},
edit() {
this.preValue = this.value;
this.preSelected = this.selectedLan;
this.editable = true;
}
selectedTitle 是通过计算属性得到的,select-option的value值绑定的是languages的每一项的language属性,即“zh、en、ja”,但文本我们要显示被选中的languages项的title属性,所以需要遍历一遍languages,找到对应的一项,拿到他的title值:
computed: { selectedTitle() { if (this.languages.length > 0 && this.selectedLan) { const choosen = this.languages.filter( (item) => item.language == this.selectedLan )[0]; return choosen.title; } return ""; }, },
样式
<style scoped>
a {
margin: 5px;
}
.editable-cell {
margin: 0 10px;
}
.editable-cell-select-wrapper {
margin: 0 15px;
}
.editable-cell-select-text-wrapper {
margin: 0 20px;
}
.editable-cell,
.editable-cell-input-wrapper,
.editable-cell-text-wrapper,
.editable-cell-select-wrapper,
.editable-cell-select-text-wrapper,
.ant-input,
.ant-select {
display: inline-block;
}
.anticon {
margin: 0 5px;
vertical-align: middle;
}
.ant-input {
150px;
margin: 0 5px;
}
.ant-select {
80px;
}
</style>