表格行内可编辑文本组件

表格行内编辑字段是一个非常常见的做法,实现也很简单,但是不同的人往往有不同的交互方式,比如我会加个编辑按钮表示可以编辑,还有的同学会使用双击触发编辑,也有单击的,有的同学会加一个✅图标保存,有的同学会使用enter来出发报错,有的。。。 总之是能想到的就能做到。

当然也有一些现成的表格组件封装好了各种行内编辑的方法,比如 vxe-table,一个功能很丰富的表格组件。但是我只想稍微给 el-table的表格加点花样,所以自己封装一个简单的组件更加轻便。

交互操作步骤

  1. 点击带【编辑】图标的字段,切换到编辑状态,并自动focus
  2. 失焦后保存数据,如果数据无变化无需走接口

考虑到编辑数字和普通文本,区别使用了el-input和 el-input-number。

需要注意的一点就是,需要编辑后先自动聚焦,才能在失焦时触发保存,所以在此加入了指令v-focus,超级简单。

focus 指令

js 复制代码
export default {
  mounted(el: HTMLElement) {
    el.querySelector('input')?.focus()
  }
}

保存的时候,需要判断数据有没有发生变化,如果有变化才调用接口保存,否则直接变成非编辑状态即可。

接口 API 方法通过 props 传入,当然也可以写在调用该组件的父组件中,怎么灵活怎么来。

组件代码

js 复制代码
<template>
  <div>
    <span class="inline-flex items-center cursor-pointer" @click="triggerEdit" v-if="!isActive"
      >{{ value }} <el-icon color="#5F45FF" class="ml-2"><EditPen /></el-icon
    ></span>
    <el-input-number
      :min="0"
      :max="9999"
      :controls="false"
      v-model="value"
      class="w-30!"
      v-focus
      @blur="handleSortChange"
      v-else-if="type === 'number'"
    />
    <el-input
      v-model="value"
      class="w-30!"
      v-focus
      @blur="handleSortChange"
      v-else-if="type === 'string'"
    />
  </div>
</template>

<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { EditPen } from '@element-plus/icons-vue'
import { ref, computed, nextTick } from 'vue'

const props = defineProps({
  type: { type: String, default: 'string' },
  modelValue: { type: [String, Number], default: '' },
  updateApi: { type: Function, default: () => {} },
  rowData: { type: Object, default: () => {} },
  paramName: { type: String, default: '' }
})

const emits = defineEmits(['success', 'update:rowData', 'update:modelValue'])

const value = computed({
  get: () => {
    return props.modelValue
  },
  set: (val) => {
    emits('update:modelValue', val)
  }
})

const isActive = ref(false)
const oldValue = ref()

const triggerEdit = () => {
  oldValue.value = props.modelValue
  isActive.value = true
}

const handleSortChange = () => {
  if (oldValue.value === value.value) {
    isActive.value = false
    return
  }
  const postData = { ...props.rowData, [props.paramName]: value.value }
  console.log(postData)
  props
    .updateApi(postData)
    .then((res: any) => {
      console.log(res)
      if (res) {
        ElMessage.success('排序成功')
        isActive.value = false
      }
    })
    .catch(() => {
      value.value = oldValue.value
    })
}
</script>

至此,实现了一个简单的行内编辑组件,如果有时间可以扩展得更加丰富一些,比如加上数据校验。

相关推荐
2501_915918413 小时前
Web 前端可视化开发工具对比 低代码平台、可视化搭建工具、前端可视化编辑器与在线可视化开发环境的实战分析
前端·低代码·ios·小程序·uni-app·编辑器·iphone
程序员的世界你不懂4 小时前
【Flask】测试平台开发,新增说明书编写和展示功能 第二十三篇
java·前端·数据库
索迪迈科技4 小时前
网络请求库——Axios库深度解析
前端·网络·vue.js·北京百思可瑞教育·百思可瑞教育
gnip4 小时前
JavaScript二叉树相关概念
前端
attitude.x5 小时前
PyTorch 动态图的灵活性与实用技巧
前端·人工智能·深度学习
β添砖java5 小时前
CSS3核心技术
前端·css·css3
空山新雨(大队长)5 小时前
HTML第八课:HTML4和HTML5的区别
前端·html·html5
猫头虎-前端技术6 小时前
浏览器兼容性问题全解:CSS 前缀、Grid/Flex 布局兼容方案与跨浏览器调试技巧
前端·css·node.js·bootstrap·ecmascript·css3·媒体
阿珊和她的猫6 小时前
探索 CSS 过渡:打造流畅网页交互体验
前端·css