欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-14 14:29:45
最近在做可编辑特定列的单元格的elementui table,看了n多的开源、文章,找到一个很优雅的实现方式,分享给大家。 ps:单元格可编辑的table,用英文搜索:i...

最近在做可编辑特定列的单元格的elementui table,看了n多的开源、文章,找到一个很优雅的实现方式,分享给大家。
ps:单元格可编辑的table,用英文搜索:inline editable table with elementui 会得到高质量结果。

先上效果:

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

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>

github:

另外一个单元格编辑的例子:

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

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>

github:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。