钩子函数-生命周期

Vue.js


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-46KqKMt3-1600773945596)(assets/lifecycle.png)]

组件生命周期

组件生命周期指的是组件从创建到销毁的过程,在这个过程中的一些不同的阶段,vue 会调用指定的一些组件方法

基本生命周期函数有下面几个阶段:

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

每一个阶段都对应着 之前之后 两个函数

<!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 属性,该阶段可以通过 DOM 操作来对组件内部元素进行处理了

更新阶段

beforeUpdate()

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

updated()

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

卸载阶段

beforeDestroy()

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

destroyed()

Vue 实例销毁后调用

errorCaptured()

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

ref 与 $refs

如果我们希望获取组件节点,进行 DOM 相关操作,可以通过 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 方法将在更新队列循环结束之后立即调用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值