与前端联调时,Element UI Tree 提示:

Invalid prop: type check failed for prop "data".
Expected Array, got Object
TypeError: children.indexOf is not a function

后端返回的是树形结构,但“是树”不等于“顶层类型符合组件要求”。这次问题出在根对象与节点数组的区别。

接口根对象不是节点数组

接口结构可以简化成:

{
  "data": {
    "id": -1,
    "name": "root",
    "children": [
      { "id": 0, "name": "所有分类", "children": [] }
    ]
  }
}

response.data 是对象,response.data.children 才是数组。这里的 response 指上面这份 JSON;若 HTTP 库又包了一层响应对象,要先区分两层 data,不能机械照抄属性路径。

根据是否展示根节点选择适配方式

Element UI 的 Tree data 属性要求数组;props 可以指定显示名称与子节点字段。Element UI Tree 文档源码

以下为 Vue 2 / Element UI 风格片段:

<el-tree
  :data="treeData"
  :props="{ label: 'name', children: 'children' }"
  node-key="id">
</el-tree>
// 已从 HTTP 响应中取出的业务 JSON
const root = payload.data;

// 不显示 root,只显示它的子节点
this.treeData = root.children;

// 如果业务需要显示 root 自身,则保持最外层为数组
this.treeData = [root];

两种赋值应按需求二选一。需要额外的“所有分类”节点时,也可以构造一个带 children 的根节点,但最外层仍应是数组。

不只检查第一层

初始化 treeData 为 [],再核对所有节点的 children 是否符合约定,节点 ID 是否唯一。对于空节点,明确统一使用空数组或组件支持的缺省表示,不要混入字符串、对象等错误类型。

接口在 Postman 中能显示 JSON,只能说明它是可读取的数据,不能证明符合组件 prop 契约。先检查容器类型,再检查递归字段,比逐层重复比对字段名称更直接。