antd + vue 点击编辑文本切换成可编辑状态(附下拉框)

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>
原文地址:https://www.cnblogs.com/lindang/p/14217925.html