vue的生命周期详解:从入门到精通

Vue生命周期

在学习vue的过程中,vue的生命周期可谓是重中之重,必学的一部分。
每个 Vue 实例在被创建时都要经过一系列的初始化过程,例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。下面这张图想必大家都不陌生

生命周期图示

在这里插入图片描述
解释:首先创建一个vue实例,进行第一次初始化操作,这次初始化仅仅是初始化自己的事件和自己的生命周期,初始化完成之后,开始第二次初始化,此时会将datacomputedmethods等等的数据观测 (data observer),属性和方法的运算,event/watch 事件回调进行初始化注入,完成之后,会检查是否指定了el选项,如果指定了,或没用指定但调用了vm.$mout("el")时,继续查看是否指定了template模板,如果没用指定,则把外部的HTML作为template编译,如果指定了,则将template渲染到render函数中(当然我们也可以不使用template,直接使用render函数创建模板),然后创建vm.$el,替换掉el,此时便已经挂载完毕了,如果数据改变,则虚拟DOM重新渲染,并应用更新,当调用销毁方法是,解除绑定,销毁子组件及事件监听器。

生命周期钩子

所有的生命周期钩子自动绑定 this 上下文到实例中,因此你可以访问数据,对属性和方法进行运算,所以,不要在钩子函数定义的时候使用箭头函数,箭头函数没用 this,可能会报错 Uncaught TypeError: Cannot read property of undefined
在这里插入图片描述

我在这下面依次介绍着8个生命周期钩子!

  • beforeCreate

    在实例初始化之后,数据观测 (data observer) 和 event/watch 事件配置之前被调用。

<div id="app">
   {{ name }}
</div>
const vm = new Vue({
    el:"#app",
    data:{
        name:"monk"
    },
    beforeCreate(){
        console.log(this.name);
        console.log(this.handleFunction)
        console.log("--beforeCreate--")
    },
    methods: {
        handleFunction(){
            console.log("我是一个方法!");
        }
    },
    watch: {
        name:{
            handler(){
                console.log("我已经开始监听侦听name属性啦");
            },
            immediate:true
        }
    },
})

打印顺序:在实例初始化之后,数据观测 (data observer) 和 event/watch 事件配置之前被调用。

undefined
undefined
--beforeCreate--
我已经开始监听侦听name属性啦
  • created

    在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,event/watch 事件回调。

    如果要在第一时间调用methods中的方法,或者操作data中的数据,可在此钩子中进行操作。需要注意的是,执行此钩子时,挂载阶段还未开始,$el 属性目前不可见。此时,可以进行数据请求,将请求回来的值赋值给data中的数据。

<div id="app">
  {{ name }}
</div>
const vm = new Vue({
    el:"#app",
    data:{
        name:"monk"
    },
    created(){
        console.log(this.name);
        console.log(this.handleFunction)
        console.log(this.$el);
        console.log('----------created-------');
    },
    methods: {
        handleFunction(){
            console.log("我是一个方法!");
        }
    },
    watch: {
        name:{
            handler(){
                console.log("我已经开始监听侦听name属性啦");
            },
            immediate:true
        }
    },
})

打印顺序:此时已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。

我已经开始监听侦听name属性啦
monk
ƒ handleFunction(){console.log("我是一个方法!");}
undefined
----------created-------
  • beforeMount

    在挂载开始之前被调用,此时模板已经编译完成,只是未将生成的模板替换el对应的元素。在此钩子函数中,可以获取到模板最初始的状态。此时,可以拿到vm.$el,只不过为旧模板

const vm = new Vue({
  el: '#app',
  beforeMount () {
    console.log(this.$el);
  }
})

打印结果:可以拿到vm.$el,只不过为旧模板

<div id="app">{{ name }}</div>
  • mounted

    el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。在该钩子函数中的vm.$el为新模板。执行完该钩子函数后,代表实例已经被完全创建好。如果要在第一时间,操作页面上的dom节点时,可以在此钩子函数中操作

const vm = new Vue({
  el: '#app',
  mounted () {
    console.log(this.$el);
  }
})

打印结果:此时的模板已经是新模板

<div id="app">monk</div>
  • beforeUpdate

    数据更新时调用,发生在虚拟 DOM 打补丁之前。此时数据已经更新,但是DOM还未更新

<div id="app">
  {{ name }}
</div>
const vm = new Vue({
    el:"#app",
    data:{
        name:"monk"
    },
    beforeUpdate(){
        console.log(this.name);
        console.log(this.$el);
    }
})
vm.name = "young monk"

打印结果:此时数据和虚拟dom已经更新,但真实Dom未更新

young monk
<div id="app">young monk</div>
  • updated

    数据更改导致DOM重新渲染后,会执行该钩子函数。此时数据和dom同步。感觉不需要举例,嘿嘿嘿

  • beforeDestroy

    实例销毁之前调用。在这一步,实例仍然完全可用。可以在该钩子函数中,清除定时器。

<div id="app">
  {{ name }}
</div>
const vm = new Vue({
    el:"#app",
    data:{
        name:"monk",
        timer:null
    },
    created(){
        this.timer = setInterval(()=>{
            console.log("定时器执行!!!")
        },1000)
    },
    beforeDestroy() {
        clearInterval(this.timer)  
    }
})

打印结果:实例创建后会一直执行定时器中内容,直到执行销毁函数时 vm.$destroy(),消除定时器,结束执行

  • destroyed

    Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章