用 reactive 管理组织架构树展开/折叠状态,需在初始化时为每个节点显式定义响应式 expanded 字段并包裹整棵树;递归组件中直接修改 node.expanded 触发视图更新,避免非响应式赋值、只读数据、错误深拷贝及 key 冲突。
用 reactive 管理组织架构树的展开/折叠状态,核心是把 expanded(或 isopen)作为节点的响应式字段直接嵌入数据结构中,并在操作时同步更新。Vue 3 的响应式系统会自动触发视图重渲染,无需手动通知。
每个节点需显式声明 expanded(推荐)或 isopen 字段,且该字段必须是响应式对象的一部分。不能用普通对象属性后期添加,否则不响应:
expanded: true,且整个树用 reactive 包裹node.expanded = true 动态加字段(非响应式)expanded,需在赋值前做映射处理,例如:treedata = reactive(transformRawData(rawData))
在自定义树节点组件(如 TreeNode.vue)中,通过点击事件切换当前节点的 expanded 值:
node 作为 prop,该 node 是 reactive 对象的子项,修改它会响应node.expanded = !node.expanded,无需额外 ref 或 set
v-if="node.expanded" 控制是否渲染,避免无谓 DOM 节点node.children 并递归调用自身组件以下情况会导致展开状态不生效或视图不更新:
readonly 或来自 toRefs 解构后的普通变量(失去响应性)Array.prototype.map 或 JSON.parse(JSON.stringify()) 深拷贝后未重新 reactive
setup 中用 const tree = ref([]) 却未将节点内部字段设为响应式(应优先用 reactive 处理嵌套结构)key 不唯一,导致 Vue diff 错误复用节点,状态错乱若需默认展开某几层,或一键展开全部,可在初始化时批量设置:
node.expanded = true
expandAll(),递归调用并标记所有 expanded = true