可编辑表格以及其嵌套

文章描述了如何在Vue应用中使用AntDesignVue组件构建一个可以编辑、添加和删除层级关系的表格,包括处理数据源、响应用户操作如保存、删除和创建子项的功能。
摘要由CSDN通过智能技术生成

<template>
  <div class="wrapper">
    <a-button @click="() => createChild()">添加父级</a-button>
    <a-button @click="() => postData()">保存</a-button>
    <a-table :defaultExpandAllRows="true" :columns="columns" :data-source="dataSource">
      <template #bodyCell="{ column, record }">
        <template v-if="column.dataIndex !== 'method' && editDataSource[record.id]">
          <a-input v-model:value="editDataSource[record.id][column.dataIndex]"></a-input>
        </template>
      </template>
    </a-table>
  </div>
</template>

<script setup lang="tsx">
import type { TableProps } from 'ant-design-vue'
import axios from 'axios'
import { reactive } from 'vue'
import { ref } from 'vue'

interface ItemInter {
  paramsName: string
  paramsFrom: 'query' | 'header'
  dataType: 'int' | 'string' | 'object'
  required: boolean
  id: number
  children?: ItemInter[]
  parent?: ItemInter
}

// 删除parent
const postData = () => {
  deleteParent(dataSource.value)
  axios.post('/test', dataSource.value)
}

const deleteParent = (itemArr: ItemInter[]) => {
  itemArr.forEach((item) => {
    item.parent && delete item.parent
    if (item.children) {
      deleteParent(item.children)
    }
  })
}

const columns: TableProps<ItemInter>['columns'] = [
  { title: '参数名称', width: '200px', dataIndex: 'paramsName' },
  { title: '参数位置', dataIndex: 'paramsFrom' },
  { title: '数据类型', dataIndex: 'dataType' },
  { title: '是否必填', dataIndex: 'required' },
  {
    title: '操作',
    dataIndex: 'method',
    customRender(opt) {
      return (
        <a-space>
          {!editDataSource[opt.record.id] ? (
            <>
              <a-button onClick={() => onClickEdit(opt.record)}>编辑</a-button>
              <a-button onClick={() => onClickDelete(opt.record)}>删除</a-button>
              <a-button onClick={() => createChild(opt.record)}>添加下级</a-button>
              <a-button>码值定义</a-button>
            </>
          ) : (
            <>
              <a-button onClick={() => onClickSaveOrCancel(editDataSource[opt.record.id], true)}>
                保存
              </a-button>
              <a-button onClick={() => onClickSaveOrCancel(editDataSource[opt.record.id])}>
                取消
              </a-button>
            </>
          )}
        </a-space>
      )
    }
  }
]

const dataSource = ref<ItemInter[]>([
  { paramsName: '参数名称', id: 1, dataType: 'object', required: '是', paramsFrom: 'header' },
  { paramsName: '参数名称2', id: 2, dataType: 'object', required: '否', paramsFrom: 'header' }
])

// const isEdit = ref<number[]>([])
const editDataSource = reactive<{ [key: number]: ItemInter }>({})

const onClickEdit = (item: ItemInter) => {
  editDataSource[item.id] = { ...item }
}

const onClickSaveOrCancel = (nowEditItem: ItemInter, isSave: boolean = false) => {
  // 保存:找到当前正在被编辑的那一条 然后 替换掉原数组中对应的那一条  最后 删除对象中id为当前id的这一条
  // 如果有父亲,那么久从父亲的children中找到当前这一条,如果没有,就直接从dataSource里面去改
  const nowFindDataSource = nowEditItem.parent?.children || dataSource.value
  if (isSave) {
    const index = nowFindDataSource.findIndex((item) => item.id === nowEditItem.id)
    nowFindDataSource[index] = nowEditItem
  }
  // 删除对象中的某一项
  delete editDataSource[nowEditItem.id]
}

const createChild = (parentItem?: ItemInter) => {
  const id = Math.floor(Math.random() * 10000)
  const item: ItemInter = {
    paramsName: '',
    id,
    dataType: 'object',
    required: false,
    paramsFrom: 'header'
  }
  if (!parentItem) {
    dataSource.value.push(item)
  } else {
    const parent = parentItem
    parentItem.children = parentItem.children || []
    item.parent = parent
    parentItem.children.push(item)
  }
  editDataSource[id] = item
}

const onClickDelete = (deleteItem: ItemInter) => {
  // 1.删除父亲,从dataSource中删除id为当前父亲的这个id的这一项-----我怎么知道当前是父亲
  // 2. 删除儿子,从父亲的children中删除id为当前儿子的id的这一项----怎么知道我的父亲是谁
  // const parentItem = {parasName:'接口名称',childrend:[]}
  // const dataSrouce = [
  // parentItem
  // ]
  // parentItem.childrend.push({paramsName:'子接口名称',parent:parentItem})
  if (!deleteItem.parent) {
    const index = dataSource.value.findIndex((item) => item.id === deleteItem.id)
    dataSource.value.splice(index, 1)
  } else {
    const parent = deleteItem.parent
    const index = parent.children.findIndex((item) => item.id === deleteItem.id)
    parent.children?.splice(index, 1)
  }
}

// const data = {paramsName:'参数名称',child:{paramsName:'儿子参数名称'}}

// const data2 = {...data}
// // {paramsName:data.paramsName,child:{...data.child}}

// // data2.paramsName = '11111'
// // console.log(data.paramsName)
// data2.child.paramsName = '11111'
// console.log(data.child.paramsName)
</script>

<style></style>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值