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 { width: 150px; margin: 0 5px; } .ant-select { width: 80px; } </style>