如何在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
相关产品推荐
相关产品推荐

