面试题答案
一键面试-
假设树形结构数据格式: 假设树形结构数据的每个节点具有以下格式:
const node = { name: '节点名称', count: 1, // 该节点自身代表的人数 children: [] // 子节点数组 };
-
使用Vue.js的
derived
计算属性(这里以Vuex的getter
类似概念为例,因为Vuex的getter
可理解为一种特殊的derived
计算属性):const store = { state: { rootNode: { name: '根节点', count: 1, children: [ { name: '子节点1', count: 2, children: [] }, { name: '子节点2', count: 3, children: [ { name: '孙节点1', count: 1, children: [] } ] } ] } }, getters: { totalPeople(state) { function countPeople(node) { let total = node.count; if (node.children && node.children.length > 0) { for (let child of node.children) { total += countPeople(child); } } return total; } return countPeople(state.rootNode); } } };
在上述代码中:
- 我们定义了一个递归函数
countPeople
,它接收一个节点作为参数。 - 对于每个节点,先将其自身的
count
值累加到total
中。 - 如果该节点有子节点,则遍历子节点,递归调用
countPeople
函数,并将返回值累加到total
。 - 最后,
getters
中的totalPeople
返回对根节点调用countPeople
的结果,从而得到整个组织结构中的总人数。 - 当
state.rootNode
中的任何数据(包括子节点的数据)发生变化时,由于Vue的响应式系统,totalPeople
计算属性会自动重新计算。
- 我们定义了一个递归函数
-
如果使用MobX(其
derived
计算属性更直接):import { makeObservable, observable, action, computed } from'mobx'; class Node { constructor(name, count) { this.name = name; this.count = count; this.children = []; makeObservable(this, { name: observable, count: observable, children: observable, totalPeople: computed }); } } class Store { constructor() { this.rootNode = new Node('根节点', 1); makeObservable(this, { rootNode: observable, totalPeople: computed }); } @computed get totalPeople() { function countPeople(node) { let total = node.count; if (node.children && node.children.length > 0) { for (let child of node.children) { total += countPeople(child); } } return total; } return countPeople(this.rootNode); } } const store = new Store();
在上述代码中:
- 定义了
Node
类,并使用makeObservable
使节点的属性可观察。 Store
类包含根节点,并定义了totalPeople
计算属性。totalPeople
计算属性同样通过递归的方式计算整个树形结构中的总人数。- 当
rootNode
及其子节点的任何可观察属性发生变化时,totalPeople
会自动更新。
- 定义了