双击编辑el-table的单元格

1、目标效果

        源码全部写在App.vue和 main.js中,复制粘贴即可!

         未双击单元格前

        双击单元格中,并修改单元格数据

        

        单元格失去焦点

2、原理解释

(1)单元格双击事件参考官方文档:

(2)el-table刷新要求绑定el-table的key要发生变化才会刷新

(3)如何控制指定单元格的显示与隐藏?

        查看一下cell-dblclick(row, column)的row、column是什么?都是对象

         我们可以往row里面添加一个属性来唯一标识某一行的数据,双击时使这特殊属性为true,输入框失去焦点时则设置特殊属性为false,并且输入框的显示与隐藏通过v-if与特殊属性绑定。

        

   

(4)@keyup.enter.native为回车事件、@blur为失焦事件,两个指向同一个方法,完成后续接口请求 

 

(5)双击表格时还要避免额外刷新表格、以及多个输入框处于显示状态,要做如下判断 

(6)全局注册自定义焦点指令

 

3、源码

main.js 

import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.config.productionTip = false
Vue.use(ElementUI);

// 全局自定义指令
Vue.directive('focus', {
  inserted(el, binding) {
    el.querySelector('input').focus()
  }
})

new Vue({
  render: h => h(App),
}).$mount('#app')

App.vue

<template>
  <div id="app">
    <el-table :data="tableData" border style="width: 100%" :key="key" @cell-dblclick="doubleClick">
      <el-table-column prop="date" label="日期" width="180">
      </el-table-column>
      <el-table-column prop="name" label="姓名" width="180">
      </el-table-column>
      <el-table-column prop="address" label="地址">
        <template slot-scope="scope">
          <el-input v-focus v-if="scope.row[scope.column.property + 'Show']" clearable v-model="scope.row.address"
            @keyup.enter.native="onBlur(scope.row, scope.column)" @blur="onBlur(scope.row, scope.column)"></el-input>
          <span v-else>{{ scope.row.address }}</span>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>
 
<script>

export default {
  name: 'App',
  data() {
    return {
      key: Math.random(),
      tableData: [{
        date: '2016-05-02',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1518 弄'
      }, {
        date: '2016-05-04',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1517 弄'
      }, {
        date: '2016-05-01',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1519 弄'
      }, {
        date: '2016-05-03',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1516 弄'
      }]
    }
  },
  methods: {
    // 双击单元格触发事件
    doubleClick(row, column) {
      // 避免点击过快导致多个输入框处于焦点状态
      row[column.property + 'Show'] = false

      // 避免点击其他单元格导致表格刷新 
      if (!['address'].includes(column.property)) return
      row[column.property + 'Show'] = true
      this.updateTable()
    },
    //输入框失焦事件
    onBlur(row, column) {
      row[column.property + 'Show'] = false
      this.updateTable()

      // 请求后台更改数据
    },
    //更新表格
    updateTable() {
      this.key = Math.random()
    },
  }
}
</script>
 
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
<think>嗯,用户想用Element Plus的el-table实现单元格编辑功能。首先,我需要回忆一下Element Plus的文档和相关组件。记得el-table本身不直接支持可编辑单元格,但可以通过自定义模板和组件组合来实现。 首先,用户可能需要点击单元格进入编辑状态。这时候应该用作用域插槽(scoped slot)来自定义单元格内容。当点击时,显示一个输入框,否则显示普通文本。需要用到v-if或v-show来控制显示状态。 然后,数据绑定是关键。el-table的数据通常是数组对象,每个单元格对应一个属性。在编辑时,需要将输入框的值绑定到对应的数据属性上。可能需要使用v-model来实现双向绑定,但要注意作用域的问题,可能需要通过事件来更新数据。 接下来要考虑的是触发编辑的方式,比如单击或双击。用户可能需要通过事件处理函数来切换编辑状态。这时候需要给单元格添加@click或者@dblclick事件,并在处理函数中改变编辑状态变量。 另外,编辑完成后,可能需要触发保存操作。比如在输入框失去焦点时保存数据,或者按回车键保存。这需要监听输入框的blur事件或keyup.enter事件,然后调用保存函数更新数据。 还有样式的问题,编辑状态下可能需要高亮显示,或者调整输入框的大小以适应单元格。这时候需要添加一些CSS类,或者内联样式来改善用户体验。 可能还需要处理表单验证,比如输入的内容是否符合要求。可以在保存数据前进行检查,或者使用Element Plus的表单验证组件。 另外,用户可能希望批量编辑多个单元格,这时候需要管理多个编辑状态,可能需要一个对象来记录每个单元格是否处于编辑模式,比如使用行的id和字段名作为键来存储状态。 还要考虑性能问题,特别是在大数据量的情况下,频繁的重新渲染可能会影响性能。这时候需要确保数据更新是响应式的,并且合理使用key属性来优化渲染。 最后,参考Element Plus的官方文档和示例代码,确保实现方式符合最佳实践,避免使用过时的API或方法。可能需要查看社区中的常见解决方案,比如使用el-input组件结合作用域插槽来实现可编辑单元格。 总结一下,步骤大致是:使用作用域插槽自定义单元格内容,通过事件切换编辑状态,绑定输入框到数据,处理保存逻辑,以及样式和验证的优化。同时要注意状态管理和性能问题。</think>### Element Plus el-table实现单元格编辑功能步骤 #### 一、基础实现方案 1. **使用作用域插槽** 通过`#default="scope"`自定义单元格内容,结合`v-if`切换输入框和普通文本状态: ```vue <el-table :data="tableData"> <el-table-column prop="name"> <template #default="scope"> <el-input v-if="scope.row.editable" v-model="scope.row.name" @blur="saveEdit(scope.row)" /> <span v-else @click="toggleEdit(scope.row)">{{ scope.row.name }}</span> </template> </el-table-column> </el-table> ``` 2. **数据响应处理** 使用`reactive`创建响应式数据,通过`Object.assign`触发视图更新: ```javascript const tableData = reactive([/* 数据数组 */]); const toggleEdit = (row) => { row.editable = !row.editable; Object.assign(row, row); // 触发响应式更新 } ``` #### 二、进阶优化方案 1. **自动聚焦优化** 使用自定义指令实现输入框自动聚焦: ```javascript app.directive('focus', { mounted(el) { el.querySelector('input').focus() } }) ``` 模板中增加指令: ```vue <el-input v-if="scope.row.editable" v-focus v-model="scope.row.name" /> ``` 2. **验证扩展** 结合Element Plus的`Form`组件进行数据校验: ```vue <el-form :model="scope.row" :rules="rules"> <el-form-item prop="name"> <el-input v-if="scope.row.editable" v-model="scope.row.name" @blur="validateField(scope.row)" /> </el-form-item> </el-form> ``` #### 三、完整实现示例 ```vue <template> <el-table :data="tableData" style="width: 100%"> <el-table-column prop="date" label="日期" width="180" /> <el-table-column prop="name" label="姓名"> <template #default="scope"> <div @click="handleClick(scope)"> <el-input v-if="scope.row.editable" v-focus v-model="scope.row.name" size="small" @blur="handleBlur(scope)" @keyup.enter="handleBlur(scope)" /> <span v-else>{{ scope.row.name }}</span> </div> </template> </el-table-column> </el-table> </template> <script setup> import { reactive } from 'vue'; const tableData = reactive([ { date: '2023-07-20', name: '张三', editable: false }, { date: '2023-07-21', name: '李四', editable: false } ]); const handleClick = (scope) => { if (!scope.row.editable) { scope.row.editable = true; Object.assign(scope.row, scope.row); } }; const handleBlur = (scope) => { scope.row.editable = false; Object.assign(scope.row, scope.row); console.log('保存数据:', scope.row); }; </script> ```
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值