You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js树形层级表格无法显示JSON数据问题求助

问题描述

尝试用Vue.js将JSON数据展示为树形层级表格,但表格内无数据显示。已确认JSON文件路径正确、格式无误,目标是创建带层级删除按钮的树形表格,本人刚接触Vue.js,数据处理方式可能不够优化。

HTML代码

<div id="app">
  <table>
    <thead>
      <tr>
        <th>Name</th>
        <th>Parent</th>
        <th>Actions</th>
      </tr>
    </thead>
    <tbody>
      <!-- 渲染顶级节点 -->
      <tr v-for="item in items" :key="item.id">
        <td>{{ item.name }}</td>
        <td>{{ item.parent }}</td>
        <td>
          <button @click="toggleChildren(item)">Toggle Children</button>
          <button @click="deleteItem(item)">Delete</button>
        </td>
      </tr>
      <!-- 渲染展开的子节点,用缩进区分层级 -->
      <tr 
        v-for="child in getExpandedChildren(items)" 
        :key="child.id"
        style="padding-left: 20px; background-color: #f5f5f5;"
      >
        <td>{{ child.name }}</td>
        <td>{{ child.parent }}</td>
        <td>
          <button @click="toggleChildren(child)">Toggle Children</button>
          <button @click="deleteItem(child)">Delete</button>
        </td>
      </tr>
    </tbody>
  </table>
</div>

Vue.js代码

new Vue({
  el: '#app',
  data: {
    items: []
  },
  created() {
    // 在Vue生命周期钩子中发起请求,更符合框架规范
    fetch('data/vue-data.json')
      .then(response => response.json())
      .then(data => {
        // 给所有节点初始化响应式的展开状态
        this.items = this.initNodeVisibility(data.items);
      })
  },
  methods: {
    // 递归初始化所有节点的展开状态,确保Vue能检测到属性变化
    initNodeVisibility(nodes) {
      return nodes.map(node => {
        node.childrenVisible = false;
        if (node.children && node.children.length) {
          node.children = this.initNodeVisibility(node.children);
        }
        return node;
      });
    },
    toggleChildren(item) {
      item.childrenVisible = !item.childrenVisible;
    },
    // 删除节点:区分顶级节点和子节点处理逻辑
    deleteItem(target) {
      // 先检查是否是顶级节点
      const topIndex = this.items.findIndex(item => item.id === target.id);
      if (topIndex !== -1) {
        this.items.splice(topIndex, 1);
        return;
      }
      // 递归查找父节点并移除子项
      this.findParentAndRemove(this.items, target);
    },
    findParentAndRemove(nodes, target) {
      for (let node of nodes) {
        if (node.children) {
          const childIndex = node.children.findIndex(child => child.id === target.id);
          if (childIndex !== -1) {
            node.children.splice(childIndex, 1);
            return;
          }
          this.findParentAndRemove(node.children, target);
        }
      }
    },
    // 扁平化处理所有展开的子节点,用于表格渲染
    getExpandedChildren(nodes) {
      let result = [];
      nodes.forEach(node => {
        if (node.childrenVisible && node.children) {
          result.push(...node.children);
          // 递归处理子节点的子节点
          result.push(...this.getExpandedChildren(node.children));
        }
      });
      return result;
    }
  }
});

关键修复&优化点

  • 响应式属性初始化:Vue无法检测对象新增的属性,必须在获取数据后给所有节点(包括子节点)初始化childrenVisible,确保视图能响应状态变化。
  • 表格结构修正:原代码中<template>直接嵌套在<tr>内不符合HTML规范,改用扁平化子节点的方式渲染,同时用样式做层级区分。
  • 删除功能实现:区分顶级节点和子节点的删除逻辑,递归查找父节点并移除目标子项。
  • 生命周期优化:将数据请求移到Vue的created钩子中,符合框架生命周期流程,代码更易维护。

内容的提问来源于stack exchange,提问作者Petr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 02:45:15