MST
星途 面试题库

面试题:Svelte derived计算属性的复杂应用

假设你有一个包含多个层级数据结构的Store,例如一个表示组织结构的树形结构数据。如何使用derived计算属性来计算整个组织结构中的总人数,并且在数据结构中的任何节点数据发生变化时,这个计算结果能自动更新?
10.5万 热度难度
前端开发Svelte

知识考点

AI 面试

面试题答案

一键面试
  1. 假设树形结构数据格式: 假设树形结构数据的每个节点具有以下格式:

    const node = {
        name: '节点名称',
        count: 1, // 该节点自身代表的人数
        children: [] // 子节点数组
    };
    
  2. 使用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计算属性会自动重新计算。
  3. 如果使用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会自动更新。