当前位置: 移动技术网 > IT编程>脚本编程>vue.js > 优雅的elementUI table单元格可编辑实现方法详解

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

2019年05月29日  | 移动技术网IT编程  | 我要评论

狂龙惊艳,平顶山新闻,诱人的恶魔之吻漫画

最近在做可编辑特定列的单元格的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>

github:

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

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:

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网