Omi框架学习之旅

生命周期

nameavatarscompany
constructor 构造函数 new的时候
install 初始化安装,这可以拿到用户传进的data进行处理 实例化
installed 安装完成,HTML已经插入页面之后执行 实例化
uninstall 卸载组件。执行remove方法会触发该事件 销毁时
beforeUpdate 更新前 存在期
afterUpdate 更新后 存在期

示意图

以上是官网的,看着让人还是挺明白的。但是我还是喜欢用我的理解解说一把。

生命周期指一个对象的生老病死。具体来说是继承Omi.Component类的子类的实例的生命周期。

1. 当我们 new 子类的时候, 子类的实例会得到Omi.Component类的所以属性和方法。

2. 当我们使用Omi.render方法时,其实调用的是Component类上的_render方法,在这个方法前后会分别调用install和installed方法,就如上图的左边部分。

3. 实例的存在期呢,我们经常会调用updade方法更新dom节点,那在这个update方法之前会分别调用beforeUpdate和afterUpdate,就如上图的右边部分。

4. 实例销毁期,就是就是调用实例的remove方法,期间也会调用update方法(那么必然会调用beforeUpdate,afterUpdate方法),之后呢会调用uninstall方法。就如上图的右下角部分。

老规矩:先上demo代码, 然后提出问题, 之后解答问题, 最后源码说明。

        class Timer extends Omi.Component {
            constructor(data) {
                super(data);
            }

            install() {
                console.log('install');
                this.data = {
                    secondsElapsed: 0
                };
            }

            tick() {
                this.data.secondsElapsed ++;
                this.update();
            }

            installed() {
                console.log('installed');
                this.interval = setInterval(() => {
                    this.tick();
                }, 1000);
            }

            uninstall() {
                console.log('uninstall');
                clearInterval(this.interval);
            }

            style() {
                return `
                    .num {
                        color: red;
                    }
                `;
            }

            beforeUpdate() {
                console.log('beforeUpdata');
            }

            render() {
                console.log('render');
                return `
                    <div>
                        Seconds Elapsed:
                        <span class="num">
                            {{secondsElapsed}}
                        </span>
                    </div>
                `;
            }

            afterUpdate() {
                console.log('afterUpdate');
            }


        };

        var time = new Timer();
        Omi.render(time, '#app');

        setTimeout(() => {
            time.remove();
            console.log('已卸载!');
        }, 10000);

demo的疑问和疑问的说明:

疑问1:

Omi.render(time, '#app');的時候是不是就执行了install 和 installed 方法 啊?

答:是的,一般可以在install方法中给实例设置数据, installed方法中update设置好的数据。怎么实现的如下:



上图中的2那个方法主要用来遍历实例是否还有孩子,有的话就遍历孩子,调用孩子的installed方法。如果孩子还有孩子就递归

    _childrenInstalled(root){    // 实例
        root.children.forEach((child) => {    // 遍历实例的每一个孩子
            this._childrenInstalled(child);    // 递归(看看自己的孩子还有没有孩子children)
            child.installed();    // 调用孩子实例installed方法
        });
    }

3那边的代码就执行installed方法。

这就是使用omi.render方法时要走的过程。

疑问2:
更新节点使用update方法,这个update到底做了什么?

答:
这个的要细细看来了,如下



1 这里调用了beforeUpdate方法。
2 这里上面有解释,看代码,如下:
    _childrenBeforeUpdate(root) {    // 实例的孩子render方法前的回调
        root.children.forEach((child)=>{
            child.beforeUpdate();    // 跟新孩子的beforeUpdate方法回调
            this._childrenBeforeUpdate(child);    // 孩子的孩子
        });
    }

  3 这里就是重新生成html css 事件转换,但是并不是无脑innerHTML,而是通过morphdom(this.node, this.HTML);来跟新节点的,这个morphdom不是虚拟dom,只是局部跟新dom节点,感兴趣的可以看看他的源码。

  4 这里看看代码

    _childrenAfterUpdate(root){
        root.children.forEach((child)=>{
            this._childrenAfterUpdate(child);    // 孩子的孩子的afterUpdate方法
            child.afterUpdate();    // 孩子的afterUpdate方法
        });
    }

  5 那里就是调用自身的afterUpdate()方法,至此结束了。


疑问3:
实例的remove方法帮我们做了啥啊?

答:帮我们update了节点,只不过把节点改成了input节点影藏节点,然后调用了uninstall方法。如下:


咋们直接进入1方法去看看


1 和 3 就是所谓生命周期的方法调用,我们进入2看看去,


其实要看的代码只是画圈的那个,我们进1看看,怎么帮我们生成一个影藏节点的,代码如下



之后就把以前的this.node节点直接换成这个创建好的节点。然后回到remove方法中的uninstall方法,就完了。


ps:
了解omi.Component实例的生命周期,当和子组件搭配时,可以很清楚了自己干了啥。
原文地址:https://www.cnblogs.com/sorrowx/p/6612262.html