You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

2.5 KiB

组件生命周期与Model状态控制

新接触FineUI的人很容易搞不清组件生命周期,写出不恰当的状态控制代码

误区:在mounted的时候异步初始化数据

举一个常见的例子: 下面的书写形式,在组件mounted之后再去发送请求初始化状态,而后由watch调用组件的setSelected方法修改状态

这样有什么不好吗? 首先请求过慢的话会导致switch开关闪一下,其次mounted之后再修改组件会导致无谓的回流重绘

class Model extends Model {
    state() {
        return {
            clusterOpen: false
        };
    }

    actions = {
        initConfig: () => {
            //  res
            return Promise.resolve(() => {
                this.model.clusterOpen = res.clusterOpen;
            });
        }
    };
}

class Widget extends BI.Widget {

    watch = {
        clusterOpen: b => this.switch.setSelected(b)
    };

    mounted() {
        this.store.initConfig();
    }

    render() {
        return {
            type: "bi.switch",
            selected: false
        };
    }
}

恰当的方式是对需要初始化配置的场景采用异步组件形式,在beforeRender生命周期中做好状态获取,在组件被挂载到DOM上之前完成组件控制

这期间也可以根据需要做loading与loaded处理.

class Model extends Model {
    state() {
        return {
            clusterOpen: false
        };
    }

    actions = {
        initConfig: () => {
            //  res
            return Promise.resolve(() => {
                this.model.clusterOpen = res.clusterOpen;
            });
        }
    };
}

class Widget extends BI.Widget {

    beforeRender() {
        return this.store.initConfig();
    }

    render() {
        return {
            type: "bi.switch",
            selected: this.model.clusterOpen
        };
    }
}

在初始化state的时候可以直接根据options来

封装一个独立的组件的时候,组件内部用到了model,有时候需要把外部传来的props用做初始状态

class Model extends Model {
    state() {
        const { clusterOpen } = this.options;
        return {
            clusterOpen: clusterOpen
        };
    }
}

@store(Model, {
    props: () => {
        return {
            clusterOpen: this.options.clusterOpen
        };
    }
}) 
class Widget extends BI.Widget {
    render() {
        return {
            type: "bi.switch",
            selected: false
        };
    }
}