若依 芋道 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;
相关推荐
htzyl2064 小时前
别急着上微前端:从 6 个场景倒推 Module Federation 2.0 与 qiankun 2.x 的选型
前端·微服务
verohh4 小时前
Cesium 多业务页面切换的资源隔离与架构设计:单 Viewer 复用还是多实例隔离
前端
律宏阔4 小时前
微信小程序 + Taro 从 ESLint 迁移到 Oxlint 让项目代码检查速度提升近 12 倍
前端·typescript·eslint
用户30816998764854 小时前
复制的代码为什么报错?BOM 等 10 种隐形字符 40 组实测
前端
Swot4 小时前
SvelteKit 踩坑记:+page.js 里忘了 ...data,服务端数据全没了
前端·后端·svelte
律宏阔4 小时前
微信小程序 + Taro + 多语言实现与国际化检查实录
前端·微信小程序·taro
deli0076 小时前
Redis 缓存穿透、击穿、雪崩:9 组流量实测数据库怎么被打穿
前端
江华森6 小时前
5Mbps 小水管也能扛:K3s 上 k6 压测 + HPA 弹性伸缩实测
前端
shuangyueliao6 小时前
103 个小游戏的商店素材,我一张图都没手动做:截图 / 封面 / 打包 / 提审全自动
前端
ZhengEnCi6 小时前
前端项目为什么需要一份统一的 theme.css:用 CSS 变量管住全局样式与主题切换
前端·css·前端工程化