表格行内可编辑文本组件

表格行内可编辑文本组件

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

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

交互操作步骤

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

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

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

focus 指令

export default {
  mounted(el: HTMLElement) {
    el.querySelector('input')?.focus()
  }
}

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

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

组件代码

<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>

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

原文链接:https://juejin.cn/post/7345729950458527781 作者:抹茶san

(0)
上一篇 2024年3月14日 上午11:05
下一篇 2024年3月14日 上午11:16

相关推荐

发表回复

登录后才能评论