组件的生命周期

生命周期

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

组件从创建到销毁的一系列过程叫做组件的声明周期。
vue在整个生命周期里面提供了一些函数,可以在内部实现一些业务逻辑,
并且这些函数会在一些特定的场合下去执行。(在生命周期的某一个时刻进行触发)

        组件的生命周期钩子函数大致可以分为三个阶段:初始化、运行中、销毁
        初始化阶段: beforeCreate  created    beforeMount mounted
        运行中阶段: beforeUpdate  updated
        销毁阶段:   beforeDestroy destroyed

在这里插入图片描述

  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,在这里做善后工作也可以

实例生命周期钩子

每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。

比如 created 钩子可以用来在一个实例被创建之后执行代码:

new Vue({
  data: {
    a: 1
  },
  created: function () {
    // `this` 指向 vm 实例
    console.log('a is: ' + this.a)
  }
})
// => "a is: 1"

也有一些其它的钩子,在实例生命周期的不同阶段被调用,如 mounted、updated 和 destroyed。生命周期钩子的 this 上下文指向调用它的 Vue 实例。

不要在选项属性或回调上使用箭头函数,比如 created: () => console.log(this.a) 或 vm.$watch(‘a’, newValue => this.myMethod())。因为箭头函数并没有 this,this 会作为变量一直向上级词法作用域查找,直至找到为止,经常导致 Uncaught TypeError: Cannot read property of undefined 或 Uncaught TypeError: this.myMethod is not a function 之类的错误。

来一波代码带你领略其钩子函数的风采:
HTML代码:

<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>
        </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>
    </template>

JS代码:

 //初始化阶段
        //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, document.getElementById('title'))
            },

            //4.created钩子函数内部的数据已经被挂载了,但是真实dom节点还是没有渲染出来
            //在这个钩子函数里面,如果同步的去更改数据的话,运行中钩子函数是不会执行的。
            //通常会在此钩子函数里面进入ajax的异步操作,另外还可以做一些初始化事件的绑定
            created() {
                console.log('created')
                console.log(this.msg, document.getElementById('title'))

                this.timer = setInterval(() =>{
                    this.msg++
                },3000)
            },

            //5.接下来的过程,就是组件或者实例去查找各自的模板,让后将其编译成虚拟dom,即将放入render函数中做初始化渲染的操作。
            //6.beforeMount代表dom马上就要被渲染出来了,但是还没有真正的在页面中渲染出来
            //此钩子函数与created钩子函数基本一致,可以做ajax与初始化事件的绑定操作
            beforeMount() {
                console.log('beforeMount')
                console.log(this.msg, document.getElementById('title'))
            },

            //生成好了虚拟dom,然后在render函数里面替换对应的el,渲染成真实dom节点
            //相当于在render函数里面做了一个初始化渲染的操作
            // render(){ //相当于把组件内部的render函数覆盖了。自己的render是将虚拟dom渲染成真实dom的操作
            //     console.log("render.....")
            // }
            //7.mounted钩子函数是初始化阶段的最后一个钩子函数
            //数据已经挂载完毕了,真实的dom也已经渲染出来了
            //这个钩子函数可以用来做一些实例化的相关操作 ===> 拖拽
            mounted() {
                console.log('mounted')
                console.log(this.msg, document.getElementById('title'))
            },

            //8.运行时钩子函数初始化阶段是不会主动执行的
            //只有dom挂载完毕了,
            //然后再去当数据发生变化的时候,beforeUpdate这个钩子函数才会执行
            beforeUpdate() {
                console.log('beforeUpdate')
                console.log(this.msg, document.getElementById('title'))
            },

            //9.這個鉤子函數裡面dom獲取的數據內容是更新後的內容
            //生成新的虛擬dom,與上一次的虛擬dom結構進行對比,比較出來差異(diff算法)再去進行真是dom的重新渲染操作
            //这里的updated中的真实dom里面显示的数据就是跟你在内存里面的data里的数据趋于一致
            updated() {
                console.log('updated')
                console.log(this.msg, document.getElementById('title').innerHTML)
            },

            //10.当组件销毁的时候,就会触发执行 vm.$destroy()的时候,组件就会被销毁
            //钩子函数销毁之前可以做一些清楚事件绑定,定时器操作
            beforeDestroy(){
                //清除定时器
                clearInterval(this.timer)
                console.log('beforeDestroy')
            },
            //11.组件一旦被销毁了,组件的dom结构还是存在的
            //只是组件的双向数据绑定、事件监听、watch相关的已经被移除
            destroyed(){
                console.log('destroyed')
            }
        })

        new Vue({}).$mount('#app')
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值