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

小编 2026-07-04 阅读:631 评论:0
最近在做可编辑特定列的单元格的elementUI table,看了N多的开源、文章,找到一个很优雅的实现方式,分享给大家。 PS:单元格可编辑的table,用英文搜索:Inline editable table...

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

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

\"\"

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

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

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表