若依 芋道 ruoyi-vue-pro 分离版 vue3 简单的行内编辑实现

最终实现:列表内容双击、行内编辑、控件失焦提交接口修改

一、简单实现: 有bug,双击后文本框获取不到焦点

  1. VUE相关代码:
html 复制代码
<template>
  <!-- 列表 -->
  <ContentWrap>
    <el-table :data="list" :show-overflow-tooltip="true" :stripe="true">



      <el-table-column label="流程备注" align="center" width="200">
        <template #default="scope">
          <span v-if="!scope.row.isEditing" @dblclick="startEditing(scope)" > {{ scope.row.name }} </span>
          <el-input v-else v-model="scope.row.name" @keyup.enter="stopEditing(scope)" @blur="stopEditing(scope)" />
        </template>
      </el-table-column>



    </el-table>
  </ContentWrap>
</template>
javascript 复制代码
<script lang="ts" setup>
// 获取列表数据示例:
const list = ref([]) // 列表数据(接口获取)
/** 接口查询列表数据 */
const getList = async () => {
  try {
      //查询列表数据 示例
      const data = await ContractApi.getContractPage(queryParams)
      list.value = data.list
  } finally {
    
  }
}



// 以下是行内编辑相关


let lastEditValue = "" //双击行内编辑文本内容(记录并用于判断提交时是否执行接口提交)
/** 双击文本,进入编辑状态 **/
const startEditing = (scope) => {
  lastEditValue = scope.row.name //双击行内编辑文本内容
  scope.row.isEditing = true
}
/** 回车键 或 编辑框失去焦点(如:点击编辑框外任意点),提交修改内容到接口 **/
const stopEditing = (scope) => {
  scope.row.isEditing = false
  // 行内编辑前后内容不同,提交修改后数据
  if(lastEditValue.trim() !== scope.row.name?.trim()){
    alert(scope.row.name?.trim())
    // 这里可以添加保存或其他逻辑
  }
}


</script>
  1. 后端代码:分页查询的集合对象中,新增属性 isEditing 用于标记是否是双击编辑状态
java 复制代码
/** 是否编辑状态(配合行内编辑使用):默认 否 **/
    private boolean isEditing = false;

二、双击后自动设置焦点全版本:

  1. VUE相关代码:
html 复制代码
<template>
  <!-- 列表 -->
  <ContentWrap>
    <el-table :data="list" :show-overflow-tooltip="true" :stripe="true">



      <el-table-column label="流程备注" align="center" width="200">
        <template #default="{ row, $index }">
          <span v-if="!row.isEditing" @dblclick="startEditing(row, $index)" > {{ row.name }} </span>
          <el-input v-else :ref="(el) => setInputRef(el, $index)" v-model="row.name" @keyup.enter="stopEditing(row, $index)" @blur="stopEditing(row, $index)" />
        </template>
      </el-table-column>



    </el-table>
  </ContentWrap>
</template>





<script lang="ts" setup>
import { ref, nextTick } from 'vue' //双击行内编辑聚集相关


// 获取列表数据示例:
const list = ref([]) // 列表数据(接口获取)
/** 接口查询列表数据 */
const getList = async () => {
  try {
      //查询列表数据 示例
      const data = await ContractApi.getContractPage(queryParams)
      list.value = data.list
  } finally {
    
  }
}



// 以下是行内编辑相关



// 保存每个输入框的引用(按行索引)
const inputRefs = ref([])
const setInputRef = (el, index) => {
  if (el) {
    inputRefs.value[index] = el
  }
}

/** 双击文本,进入编辑状态 **/
const startEditing = async (row, index) => {
  row._oldName = row.name // 存储旧值到行对象:双击行内编辑文本内容(记录并用于判断提交时是否执行接口提交)
  row.isEditing = true //编辑中
  // 等待 DOM 更新后聚焦
  await nextTick()
  // 获取对应行的 el-input 组件实例
  const inputInstance = inputRefs.value[index]
  if (inputInstance) {
    // 方法1:直接调用组件暴露的 focus
    inputInstance.focus?.()
    // 如果无效,降级到原生 input(但通常 focus 方法已足够)
    // inputInstance.$el.querySelector('input')?.focus()
  }
}
/** 回车键 或 编辑框失去焦点(如:点击编辑框外任意点),提交修改内容到接口 **/
const stopEditing = async (row, index) => {
  row.isEditing = false
  const oldName = row._oldName
  // 行内编辑前后内容不同,提交修改后数据
  if(oldName.trim() !== row.name?.trim()){
    try {
      await ContractApi.updateInvoice(row.id, row.name) // 发起修改
      delete row._oldName // 清除临时数据
      // await getList() // 刷新列表
    } catch {
      // await getList()
      row.name = oldName// 恢复原值
    }
  }
}


</script>
  1. 后端代码:分页查询的集合对象中,新增属性 isEditing 用于标记是否是双击编辑状态
java 复制代码
/** 是否编辑状态(配合行内编辑使用):默认 否 **/
    private boolean isEditing = false;
相关推荐
亿元程序员13 小时前
为什么现在 AI 这么发达了,还要坚持手搓教程?
前端
三小河14 小时前
在 Codex 桌面端接入 DeepSeek 模型(CC Switch 代理中转)
前端·javascript·人工智能
CoderYanger14 小时前
前端基础——JavaScript(WebAPI)代码案例
java·开发语言·前端·javascript·css·前端框架·html5
恋猫de小郭14 小时前
Shopify 从 React Native 回到 Swift/Kotlin,但是你以为有手就行??
android·前端·ios
BillKu15 小时前
Element Plus 的 el-tab-pane:lazy 的说明
前端·javascript·vue.js
爱勇宝15 小时前
《道德经》第 11 章:真正有用的,常常是你没写出来的那部分
前端·后端·产品
jearry15 小时前
WebView2 原生拖放的桥接之道:拆解 yyzTools 的 drop-zone.js
前端·c++
一位正在转型AI全栈的前端工程师15 小时前
AI 全栈学习之旅 -Week 11:从 CLI 到浏览器:用 FastAPI、SSE 和 Vue 3 做一个可审核的 ReAct Agent
前端·python
10share15 小时前
我为什么用 React 重写了一个 VitePress
前端·react.js
计算机魔术师15 小时前
GPT-6 Astra 发布后,Sebastian Raschka 解析 looped transformer 与隐藏推理链传闻
前端