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

如何在Vue中为嵌套递归树结构设置随展开调整的交替背景色

递归树组件动态交替背景色实现方案

实现该需求的核心思路是放弃通过节点层级判断背景色,改为基于当前可见节点的全局排序索引设置奇偶背景,不受节点展开收起操作影响,逻辑实现非常简单:


实现步骤

1. 根组件维护可见节点的拍平列表

在树组件的根层级新增计算属性,遍历所有节点,只收集当前处于展开状态的节点,整体拍平为一维数组,数组的顺序就是节点在页面上从上到下的渲染顺序:

// 根组件计算属性
computed: {
  visibleNodes() {
    const flattenTree = (nodeList) => {
      const result = []
      nodeList.forEach(node => {
        result.push(node)
        // 仅收集展开状态下的子节点
        if (node.expanded && Array.isArray(node.children) && node.children.length) {
          result.push(...flattenTree(node.children))
        }
      })
      return result
    }
    return flattenTree(this.originTreeData)
  }
}

2. 透传可见节点列表给所有子节点

通过provide/inject把拍平的可见节点列表透传给所有递归的Node子组件,不需要层层传props:

// 根组件逻辑(Vue3写法)
import { provide } from 'vue'
// ...
setup() {
  const visibleNodes = computed(/* 上方的拍平逻辑 */)
  provide('visibleNodes', visibleNodes)
}

3. 子节点根据自身在可见列表的索引设置背景色

在递归Node组件中注入列表,查询当前节点的索引,根据奇偶性设置背景色即可:

<!-- Node.vue 组件 -->
<template>
  <div class="tree-node" :style="{ backgroundColor: bgColor }">
    <!-- 节点内容、展开按钮等原有逻辑 -->
    <Node 
      v-for="child in node.children" 
      :key="child.id" 
      :node="child"
      v-if="node.expanded"
    />
  </div>
</template>
<script>
import { inject, computed } from 'vue'
export default {
  props: ['node'],
  setup(props) {
    const visibleNodes = inject('visibleNodes')
    const bgColor = computed(() => {
      const idx = visibleNodes.value.findIndex(item => item.id === props.node.id)
      return idx % 2 === 0 ? '#ffffff' : '#f5f7fa'
    })
    return { bgColor }
  }
}
</script>

性能优化提示

如果你的树节点数量超过1000,findIndex查询会有性能损耗,可以在拍平可见节点的时候直接给每个节点挂载临时索引属性,不需要每次查询:

// 改造拍平逻辑,直接给节点赋值临时索引
const flattenTree = (nodeList) => {
  const result = []
  nodeList.forEach(node => {
    node.__visibleIdx = result.length
    result.push(node)
    if (node.expanded && node.children?.length) {
      result.push(...flattenTree(node.children))
    }
  })
  return result
}

// 子组件直接取索引即可
const bgColor = computed(() => {
  return props.node.__visibleIdx % 2 === 0 ? '#ffffff' : '#f5f7fa'
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 04:06:04