DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加行拖拽排序功能示例5,TableView16_05 树形表格拖拽排序

发布于:2025-03-28 ⋅ 阅读:(33) ⋅ 点赞:(0)

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕

共同探索软件研发!敬请关注【宝码香车】
关注描述

csdngif标识


📚📗📕📘📖🕮💡📝🗂️✍️🛠️💻🚀🎉🏗️🌐🖼️🔗📊👉🔖⚠️🌟🔐⬇️·正文开始⬇️·🎥😊🎓📩😺🌈🤝🤖📜📋🔍✅🧰❓📄📢📈 🙋0️⃣1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣8️⃣9️⃣🔟🆗*️⃣#️⃣

DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加行拖拽排序功能示例5,TableView16_05 树形表格拖拽排序

📚前言

随着技术的不断发展和完善,DeepSeek 的应用范围也越来越广泛。其模型不仅在自然语言处理领域取得了优异的成绩,还在图像与视频分析、语音交互、编程辅助等多个领域得到了应用。在图像识别中,DeepSeek 能够准确地识别图像中的物体、场景和人物,为图像分类、目标检测等任务提供了有力支持;在语音交互方面,它能准确识别和合成语音,支持多语言和方言,为智能语音助手、语音输入等应用提供了技术保障;在编程辅助领域,DeepSeek 可以根据程序员描述的功能需求,生成相应的代码框架或完整代码片段,帮助开发者快速理解代码逻辑,检测出代码中的潜在错误和漏洞,辅助进行调试和优化,大大提高了编程效率和代码质量。

📚页面效果

DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加行拖拽排序功能示例5,TableView16_05 树形表格拖拽排序

📘组件代码

<!-- TableView16_05.vue 树形表格拖拽示例 -->
<template>
  <div class="drag-demo">
    <h2>05. 树形表格拖拽排序</h2>
    <div v-if="dragError" class="error-message">
      {
  { dragError }}
    </div>
    <Table
      :data="flattenedData"
      :columns="columns"
      draggable
      row-key="id"
      border
      stripe
      @update:data="handleDataUpdate"
    >
      <!-- 自定义名称列,显示树结构 -->
      <template #cell-name="{ row }">
        <div class="tree-cell" :style="{ paddingLeft: `${row.level * 20}px` }">
          <span 
            v-if="hasChildren(row)" 
            class="tree-icon"
            @click.stop="toggleExpand(row)"
          >
            {
  { isExpanded(row) ? '▼' : '▶' }}
          </span>
          <span v-else class="tree-icon-placeholder"></span>
          {
  { row.name }}
        </div>
      </template>
    </Table>
    
    <div class="debug-panel" v-if="showDebug">
      <h3>当前树形数据结构</h3>
      <pre>{
  { JSON.stringify(treeData, null, 2) }}</pre>
    </div>
    
    <button class="debug-toggle" @click="showDebug = !showDebug">
      {
  { showDebug ? '隐藏' : '显示' }}调试信息
    </button>
  </div>
</template>

<script setup>
import {
      ref, computed } from 'vue'
import Table from '@/components/Table/Table.vue'

// 树形数据 - 每个节点都有唯一ID和parentId
const treeData = ref([
  {
     
    id: 1,
    name: '项目计划',
    status: '进行中',
    parentId: null,
    children: [
      {
      id: 11, name: '需求分析', status: '进行中', parentId: 1 },
      {
      id: 12, name: '原型设计', status: '待处理', parentId: 1 }
    ]
  },
  {
     
    id: 2,
    name: '开发阶段',
    status: '待处理',
    parentId: null,
    children: [
      {
      id: 21, name: '前端开发', status: '待处理', parentId: 2 },
      {
      id: 22, name: '后端开发', status: '待处理', parentId: 2 }
    ]
  },
  {
     
    id: 3,
    name: '测试阶段',
    status: '未开始',
    parentId: null,
    children: [
      {
      id: 31, name: '单元测试', status: '待处理', parentId: 3 },
      {
      id: 32, name: '集成测试', status: '待处理', parentId: 3 }
    ]
  }
])

// 表格列定义
const columns = [
  {
      title: '任务名称', dataIndex: 'name', width: '250px' },
  {
      title: '状态', dataIndex: 'status', width: '120px' }
]

// 展开的节点ID
const expandedIds = ref([1, 2])
const showDebug = ref(false)
const dragError = ref(null)

// 检查节点是否有子节点
const hasChildren = (node) => {
     
  return node.isParent && treeNodeMap.value[node.id]?.children?.length > 0
}

// 检查节点是否已展开
const isExpanded = (node) => {
     
  return expandedIds.value.includes(node.id)
}

// 切换节点展开/折叠状态
const toggleExpand = (node) => {
     
  if (!hasChildren(node)) return
  
  const index = expandedIds.value.indexOf(node.id)
  if (index > -1) {
     
    expandedIds.value.splice(index, 1)
  } else {
     
    expandedIds.value.push(node.id)
  }
}

// 节点Map,用于快速查找
const treeNodeMap = computed(() => {
     
  const map = {
     }
  
  const processNode = (node) => {
     
    map[node.id] = {
      ...node }
    if (node.children && node.children.length > 0) {
     
      node.children.forEach(processNode)
    }
  }
  
  treeData.value.forEach(processNode)
  return map
})

// 将树形数据扁平化为表格数据
const flattenedData = computed(() => {
     
  const result = []
  
  const flattenNode = (node, level = 0, visible = true) => {
     
    // 创建表格行数据
    const rowData = {
     
      id: node.id,
      name: node.name,
      status: node.status,
      parentId: node.parentId,
      level,
      isParent: Boolean(node.children && node.children.length > 0),
      visible
    }
    
    // 只添加可见的节点到结果
    if (visible) {
     
      result.push(rowData)
    }
    
    // 递归处理子节点
    if (node.children && node.children.length > 0) {
     
      // 子节点只有在父节点展开时才可见
      const childVisible = visible && isExpanded({
      id: node.id })
      node.children.forEach(child => flattenNode(child, level + 1, childVisible))
    }
  }
  
  // 处理所有根节点
  treeData.value.forEach(node => flattenNode(node))
  return result
})

// 处理拖拽后的数据更新
const handleDataUpdate = (newData) => {
     
  try {
     
    // 清除之前的错误
    dragError.value = null
    
    // 构建新的树形结构
    const newTreeData = rebuildTree(newData)
    treeData.value = newTreeData
  } catch (error) {
     
    console.error('树形数据重建失败:', error)
    dragError.value = '拖拽操作导致数据结构错误,已还原'
  }
}

// 根据扁平数据重建树形结构
const rebuildTree = (flatData) => {
     
  // 创建节点映射
  const nodeMap = {
     }
  
  // 第一遍:创建所有节点
  flatData.forEach(item => {
     
    nodeMap[item.id] = {
     
      id: item.id,
      name: item.name,
      status: item.status,
      parentId: item.parentId,
      children: []
    }
  })
  
  // 第二遍:建立父子关系
  const rootNodes = []
  
  flatData.forEach(item => {
     
    const node = nodeMap[item.id]
    
    if (!item.parentId) {
     
      // 根节点
      rootNodes.push(node)
    } else if (nodeMap[item.parentId]) {
     
      // 添加到父节点的children数组
      nodeMap[item.parentId].children.push(node)
    } else {
     
      // 孤儿节点(无法找到父节点)
      rootNodes.push(node)
    }
  })
  
  return rootNodes
}
</script>