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


Posted in Javascript onDecember 23, 2018

最近在做可编辑特定列的单元格的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:https://github.com/heianxing/editable-table-idea-vue-element

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

优雅的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:https://github.com/heianxing/editable-table-component-vue-element

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

Javascript 相关文章推荐
HTML Dom与Css控制方法
Oct 25 Javascript
JQuery魔力之$(&quot;tagName&quot;)与selector
Mar 05 Javascript
引用外部js乱码问题分析及解决方案
Apr 12 Javascript
Js中的onblur和onfocus事件应用介绍
Aug 27 Javascript
Jquery EasyUI的添加,修改,删除,查询等基本操作介绍
Oct 11 Javascript
JS根据变量保存方法名并执行方法示例
Apr 04 Javascript
JQuery EasyUI 数字格式化处理示例
May 05 Javascript
Jquery时间轴特效(三种不同类型)
Nov 02 Javascript
jQuery基于muipicker实现仿ios时间选择
Feb 22 Javascript
Javascript的表单与验证-非空验证
Mar 18 Javascript
$.browser.msie 为空或不是对象问题的多种解决方法
Mar 19 Javascript
js中的面向对象之对象常见创建方法详解
Dec 16 Javascript
基于webpack4.X从零搭建React脚手架的方法步骤
Dec 23 #Javascript
JavaScript基于数组实现的栈与队列操作示例
Dec 22 #Javascript
jQuery实现侧边栏隐藏与显示的方法详解
Dec 22 #jQuery
JavaScript时间日期操作实例小结【5个示例】
Dec 22 #Javascript
JavaScript文本特效实例小结【3个示例】
Dec 22 #Javascript
JavaScript实现的鼠标跟随特效示例【2则实例】
Dec 22 #Javascript
iview实现select tree树形下拉框的示例代码
Dec 21 #Javascript
You might like
关于php操作mysql执行数据库查询的一些常用操作汇总
2013/06/24 PHP
php中PDO方式实现数据库的增删改查
2015/05/17 PHP
PHP 实现的将图片转换为TXT
2015/10/21 PHP
PHP 闭包详解及实例代码
2016/09/28 PHP
Javascript String.replace的妙用
2009/09/08 Javascript
JS分页控件 可用于无刷新分页
2013/07/23 Javascript
Javascript全局变量var与不var的区别深入解析
2013/12/09 Javascript
Javascript的setTimeout()使用闭包特性时需要注意的问题
2014/09/23 Javascript
超级给力的JavaScript的React框架入门教程
2015/07/02 Javascript
javascript实现列表切换效果
2016/05/02 Javascript
AngularJS使用自定义指令替代ng-repeat的方法
2016/09/17 Javascript
Canvas 制作动态进度加载水球详解及实例代码
2016/12/09 Javascript
js设置文字颜色的方法示例
2016/12/30 Javascript
nodejs和php实现图片访问实时处理
2017/01/05 NodeJs
Vue系列:通过vue-router如何传递参数示例
2017/01/16 Javascript
Javascript仿京东放大镜的效果
2017/03/01 Javascript
3分钟快速搭建nodejs本地服务器方法运行测试html/js
2017/04/01 NodeJs
jquery实现侧边栏左右伸缩效果的示例
2017/12/19 jQuery
JS交互点击WKWebView中的图片实现预览效果
2018/01/05 Javascript
vue拦截器实现统一token,并兼容IE9验证功能
2018/04/26 Javascript
vue3.0封装轮播图组件的步骤
2021/03/04 Vue.js
Python ORM框架SQLAlchemy学习笔记之映射类使用实例和Session会话介绍
2014/06/10 Python
pandas.DataFrame删除/选取含有特定数值的行或列实例
2018/11/07 Python
python实现烟花小程序
2019/01/30 Python
Python写捕鱼达人的游戏实现
2020/03/31 Python
浅谈CSS3 动画卡顿解决方案
2019/01/02 HTML / CSS
工程管理专业个人求职信范文
2013/12/07 职场文书
职业生涯规划书基本格式
2014/01/06 职场文书
中专毕业生个人职业生涯规划
2014/02/19 职场文书
幼儿园庆六一活动方案
2014/03/06 职场文书
2014爱耳日宣传教育活动总结
2014/03/09 职场文书
小学教师自我鉴定范文
2014/03/20 职场文书
2014年国庆节庆祝建国65周年比赛演讲稿
2014/09/21 职场文书
个人求职自荐信范文
2015/03/06 职场文书
2015年双拥工作总结
2015/04/08 职场文书
500字作文之难忘的同学
2019/12/20 职场文书