美文网首页
生命周期

生命周期

作者: lucky_yao | 来源:发表于2020-10-26 07:51 被阅读0次

    组件生命周期

    组件生命周期指的是组件从创建到销毁的过程,在这个过程中的一些不同的阶段,vue会调用指定的一些组件方法
    基本生命周期函数有下面几个阶段:

    • 创建阶段
    • 挂载阶段
    • 更新阶段
    • 卸载阶段

    每一个阶段都对应着<u>之前</u>和<u>之后</u>两个函数

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
    
        <div id="app">
            <h1>{{title}}</h1>
            <button @click="show=!show">隐藏</button>
            <hr>
            <template v-if="hasError">
                <h4>有错误发生了</h4>
            </template>
            <template v-else>
                <kkb-component v-if="show" :t="title"></kkb-component>
            </template>
        </div>
        
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    
        <script>
    
            const kkbComponent = {
                props: ['t'],
                template: `
                    <div>
                        <h1>kkbComponent - {{t.a.b}}</h1>
                    </div>
                `,
                beforeCreate() {
                    console.log('kkbComponent:beforeCreate');
                    console.log('data', this.$data);
                    console.log('el', this.$el);
                    console.log('='.repeat(100));
                },
                created() {
                    console.log('kkbComponent:created');
                    console.log('data', this.$data);
                    console.log('el', this.$el);
                    console.log('='.repeat(100));
                },
                beforeMount() {
                    console.log('kkbComponent:beforeMount');
                    console.log('data', this.$data);
                    console.log('el', this.$el);
                    console.log('='.repeat(100));
                },
                mounted() {
                    console.log('kkbComponent:mounted');
                    console.log('data', this.$data);
                    console.log('el', this.$el);
                    console.log('='.repeat(100));
                },
                beforeUpdate() {
                    console.log('kkbComponent:beforeUpdate');
                    console.log('props', this.$props);
                    console.log('='.repeat(100));
                },
                updated() {
                    console.log('kkbComponent:updated');
                    console.log('='.repeat(100));
                },
                beforeDestroy() {
                    console.log('kkbComponent:beforeDestroy');
                    console.log('this', this);
                    console.log('='.repeat(100));
                },
                destroyed() {
                    console.log('kkbComponent:destroyed');
                    console.log('this', this);
                    console.log('='.repeat(100));
                }
            }
            
            let app = new Vue({
                el: '#app',
                data: {
                    title: '开课吧',
                    show: true,
                    hasError: false
                },
                components: {
                    'kkb-component': kkbComponent
                },
    
                beforeCreate() {
                    console.log('beforeCreate');
                    console.log('data', this.$data);
                    console.log('el', this.$el);
                    console.log('='.repeat(100));
                },
                created() {
                    console.log('created');
                    console.log('data', this.$data);
                    console.log('el', this.$el);
                    console.log('='.repeat(100));
                },
                beforeMount() {
                    console.log('beforeMount');
                    console.log('data', this.$data);
                    console.log('el', this.$el);
                    console.log('='.repeat(100));
                },
                mounted() {
                    console.log('mounted');
                    console.log('data', this.$data);
                    console.log('el', this.$el);
                    console.log('='.repeat(100));
                },
                beforeUpdate() {
                    console.log('beforeUpdate');
                    console.log('props', this.$props);
                    console.log('='.repeat(100));
                },
                updated() {
                    console.log('updated');
                    console.log('='.repeat(100));
                },
                beforeDestroy() {
                    console.log('beforeDestroy');
                    console.log('this', this);
                    console.log('='.repeat(100));
                },
                destroyed() {
                    console.log('destroyed');
                    console.log('this', this);
                    console.log('='.repeat(100));
                },
                errorCaptured(err, vm, info) {
                    console.log('errorCaptured');
                    console.log(err, vm, info);
                    console.log('='.repeat(100));
                    this.hasError = true;
                    return false;
                }
            });
        </script>
    </body>
    </html>
    

    创建阶段

    beforeCreate()

    初始化阶段,应用不多

    created()

    在实例创建完成后被立即调用,该阶段完成了对data中的数据的observer,该阶段可以处理一些异步任务

    挂载阶段

    beforeMount()

    在挂载开始之前被调用,应用不多

    mounted()

    该阶段执行完了模板解析,以及挂载。同时组件根组件元素被赋给了$el属性,该阶段可以通过<u>DOM</u>操作来对组件内部元素进行处理了

    更新阶段

    beforeUpdate()

    数据更新时调用,但是还没有对视图进行重新渲染,这个时候,可以获取视图更新之前的状态

    updated()

    由于数据的变更导致的视图重新渲染,可以通过<u>DOM</u>操作来获取视图的最新状态

    卸载阶段

    beforeDestroy()

    实例销毁之前调用,移出一些不必要的冗余数据,比如定时器

    destroyed()

    Vue 实例销毁后调用

    errorCaptured()

    当捕获一个来自子孙组件的错误时被调用,此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。

    ref 与 $refs

    如果我们希望获取组件节点,进行 <u>DOM</u> 相关操作,可以通过 ref$refs 来完成

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
    
        <div id="app">
            <h1>{{title}}</h1>
            <button @click="getBoxHeight">获取 box 的高度</button>
            <button @click="getKKBComponent">获取自定义组件实例及内部方法</button>
            <hr>
            <div ref="box">
                这是内容<br>这是内容<br>这是内容<br>这是内容<br>这是内容<br>
            </div>
            <hr>
            <kkb-component ref="kkb" :t="title"></kkb-component>
        </div>
        
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    
        <script>
    
            const kkbComponent = {
                props: ['t'],
                data() {
                    return {
                        isShow: true
                    }
                },
                template: `
                    <div v-if="isShow">
                        <h1>kkbComponent - {{t}}</h1>
                    </div>
                `,
                methods: {
                    hide() {
                        this.isShow = false;
                    }
                }
            }
            
            let app = new Vue({
                el: '#app',
                data: {
                    title: '开课吧'
                },
                components: {
                    'kkb-component': kkbComponent
                },
                mounted() {
                    console.log(this.$refs.kkb);
                },
                methods: {
                    getBoxHeight() {
                        console.log( this.$refs.box.clientHeight );
                    },
                    getKKBComponent() {
                        this.$refs.kkb.hide();
                    }
                }
            });
        </script>
    </body>
    </html>
    

    ref

    给元素或组件添加 ref 属性,则该元素或组件实例对象将被添加到当前组件实例对象的 $refs 属性下面

    $refs

    该属性的是一个对象,存储了通过 ref 绑定的元素对象或者组件实例对象

    nextTick

    当数据更新的时候,视图并不会立即渲染,这个时候我们期望获取到视图更新后的数据,可以通过 nextTick 来进行操作

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
    
        <div id="app">
            <h1>{{title}}</h1>
            <button @click="setBoxContent">设置新的内容</button>
            <hr>
            <div ref="box" style="background: red" v-html="content"></div>
        </div>
        
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    
        <script>
            
            let app = new Vue({
                el: '#app',
                data: {
                    title: '开课吧',
                    n: 1
                },
                computed: {
                    content() {
                        return new Array(this.n).fill(this.title).join('<br>');
                    }
                },
                methods: {
                    setBoxContent() {
                        this.n++;
                        this.$nextTick(_=>{
                            console.log( this.$refs.box.clientHeight );
                        })
                    }
                }
            });
        </script>
    </body>
    </html>
    

    nextTick 方法将在更新队列循环结束之后立即调用

    相关文章

      网友评论

          本文标题:生命周期

          本文链接:https://www.haomeiwen.com/subject/afviyktx.html