Vue组件的生命周期

生命周期

每一个组件或者实例都会经历一个完整的生命周期,总共分为三个阶段:初始化、运行中、销毁
在这里插入图片描述

  1. 一个组件或者实例的生命周期都是通过new开始的
  2. 实例化之后,内部会做一些初始化事件与生命周期相关的配置
初始化阶段

初始化阶段会执行四个钩子函数

  1. beforeCreate
    在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
  2. created
    在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前尚不可用。
  3. beforeMount
    在挂载开始之前被调用:相关的 render 函数首次被调用。
  4. mounted
    实例被挂载后调用,这时 el 被新创建的 vm. e l 替 换 了 。 如 果 根 实 例 挂 载 到 了 一 个 文 档 内 的 元 素 上 , 当 m o u n t e d 被 调 用 时 v m . el 替换了。 如果根实例挂载到了一个文档内的元素上,当mounted被调用时vm. elmountedvm.el也在文档内。
运行阶段

运行阶段会执行两个钩子函数

  1. beforeUpdate
    数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
  2. updated
    由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
    当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。
销毁

销毁会执行两个钩子函数

  1. beforeDestroy
    实例销毁之前调用。在这一步,实例仍然完全可用。
  2. destroyed
    实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。

过程

  1. 实例、组件通过new Vue() 创建出来之后会初始化事件和生命周期,然后就会执行beforeCreate钩子函数,这个时候,数据还没有挂载到,只是一个空壳,无法访问到数据和真实的dom,一般不做操作

  2. 挂载数据,绑定事件等等,然后执行created函数,这个时候已经可以使用到数据,也可以更改数据,在这里同步更改数据不会触发updated函数,一般可以在这里做初始数据的获取。 做异步ajax,绑定初始化事件

  3. 接下来开始找实例或者组件对应的模板,编译模板为虚拟dom放入到render函数中准备渲染,然后执行beforeMount钩子函数,在这个函数中虚拟dom已经创建完成,马上就要渲染,在这里也可以更改数据,不会触发updated,这是在渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始化数据的获取

  4. 接下来开始render,渲染出真实dom,然后执行mounted钩子函数,此时,组件已经出现在页面中,数据、真实dom都已经处理好了,事件都已经挂载好了,可以在这里操作真实dom等事情…

  5. 当组件或实例的数据更改之后,会立即执行beforeUpdate,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染,一般不做什么事儿

  6. 当更新完成后,执行updated,数据已经更改完成,dom也重新render完成,可以操作更新后的dom

  7. 当经过某种途径调用$destroy方法后,立即执行beforeDestroy,一般在这里做一些善后工作,例如清除计时器、清除非指令绑定的事件等等

  8. 组件的数据绑定、监听…去掉后只剩下dom空壳,这个时候,执行destroyed,在这里做善后工作也可以

代码展示
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <my-component></my-component>
    </div>
    <template id="my-component">
        <div>
            <h1 id="title">hello---{{msg}}</h1>
            <p><input type="text" v-model="msg"></p>
            <button @click="destroy">销毁组件</button>
        </div>
    </template>
</body>
<script src="../vue.js"></script>
<script>

//初始化阶段
//1.一个组件或者实例的生命周期都是通过new开始的
//2.实例化之后,内部会做一些初始化事件与生命周期相关的配置
Vue.component("my-component",{
    template:"#my-component",
    data(){
        return {
            msg:1
        }
    },
    methods:{
        destroy(){
            this.$destroy()
        }
    },
    //3.这个钩子函数初始化的时候立即执行,此钩子函数里面获取不到数据
    //同时页面中的真实dom节点也没有挂载出来,null
    beforeCreate(){
        console.log("beforeCreate......")
        console.log(this.msg)
        console.log(document.getElementById("title"))
    },
    //4.created钩子函数内部的数据已经被挂载,但是真实dom节点仍然未被渲染
    //在这个钩子函数里面,如果同步的去更改数据的话,运行中钩子函数是不会执行的。
    //通常会在这个钩子函数里面进行ajax异步操作,另外还可以做一些初始化事件的绑定
    created(){
        //this.msg = 2
        console.log("created......")
        console.log(this.msg)
        console.log(document.getElementById("title"))
        //定时器
        this.timer = setInterval(()=>{
            console.log(111)
            this.msg++
        },3000)
    },
    //5.接下来的过程,就是组件或实例去查找各自的模板,然后将其编译成虚拟dom,即将其放入render函数中做初始化渲染
    //6.beforeMount代表dom马上就要渲染出来,但是还没有真正的渲染出
    //此钩子函数与created基本一致,可以做ajax与事件初始化绑定操作
    beforeMount(){
        console.log("beforeMount......")
        console.log(this.msg)
        console.log(document.getElementById("title"))
    },
    //生成好了虚拟dom,然后在render函数里面替换对应的el,渲染真实dom节点
    //相当于在render函数里面做一个初始换渲染操作
    /*render(){
        console.log("render......")
    }*/
    //7.mounted钩子函数是初始化阶段最后一个钩子函数
    //数据已经挂载完毕,真实dom已经渲染出来
    //这个钩子函数可以用来做一些实例化的相关操作 例如:拖拽效果
    mounted(){
        console.log("mounted......")
        console.log(this.msg)
        console.log(document.getElementById("title"))
    },
    //8.运行时钩子函数初始化阶段是不会执行的
    //只有dom挂载完毕,当数据发生变化的时候,beforeUpdate钩子函数才会执行
    beforeUpdate(){
        console.log("beforeUpdate......")
        console.log(this.msg)
        console.log(document.getElementById("title").innerHTML)
    },
    //9.这个钩子函数里面dom获取的数据内容是更新后的内容
    //生成新的虚拟dom,与上一次的虚拟dom结构进行对比,比较出来差异(diff)再去进行真实的dom渲染
    //这里的updated中的真实dom里面显示的数据,跟在内存里面的data数据趋于一致
    updated(){
        console.log("updated......")
        console.log(document.getElementById("title").innerHTML)
    },
    //10.组件销毁就会触发,vm.$destroy()方法被执行的时候,组件就会销毁
    //销毁之前,分手之前,在吵架
    //做一些清除事件绑定,清除定时器相关操作
    beforeDestroy(){
        console.log("beforeDestroy......")
        clearInterval(this.timer)
    },
    //11.完成时,吵架结束,已经分手
    //数据绑定不存在了
    //销毁后dom结构还存在,分手后以前的回忆没有忘记,未清除
    destroyed(){
        console.log("destroyed......")
    }  
})


new Vue({}).$mount("#app")

</script>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值