黑马程序员技术交流社区

标题: 【西安校区】【干货】详解vue生命周期 [打印本页]

作者: 逆风TO    时间: 2020-3-31 11:29
标题: 【西安校区】【干货】详解vue生命周期
生命周期定义每个vue实例在被创建之前都要经过一系列的初始化过程,这个过程就是vue的生命周期。详细来说,就是Vue实例从开始创建,初始化数据,编译模板,挂在dom->渲染,更新->渲染,卸载等一系列过程,我们称这是vue的生命周期,各个阶段有相对应的事件钩子。
钩子函数:当代码执行到特定阶段的时候会调用的函数,也是回掉函数。生命周期示意图

代码解析生命周期1.new Vue() 创建实例2.初始化事件和生命周期3.beforeCreate

代码:
[Java] 纯文本查看 复制代码
 let vm = new Vue({
    // 当前这个实例他的父亲是谁 儿子谁 有一套
    beforeCreate(){
        console.log(this);
        console.log('---beforeCreate---');   
    },
    data(){
        return{
            msg:'hello'
        }
    }
})




从打印出来的this,可以看到此时发布订阅 emit等vue原生API已经初始化完成。但是不能访问到data,computed,watch,methods上的方法和数据。这个钩子函数不能做业务逻辑,一般情况下这个钩子函数可以做的事情:在每个组建中增加一些特定的属性,例如混合。
4.初始化注入和校验5.created这个实例已经实现了数据劫持,把方法、计算属性 也都挂载到了实例,不能获取到真实的dom元素。不能访问到 ref属性内容未空数组。这个钩子函数可以发送axios请求把请求回来的数据保存到data中。

[Java] 纯文本查看 复制代码
let vm = new Vue({
    beforeCreate(){
        console.log(this);
        console.log('---beforeCreate---');
    },
    created(){
        console.log(this);
        console.log('---created---');
        debugger;
    },
    data(){
        return{
            msg:'hello'
        }
    }
})


6.beforemount
接下来就是渲染,但是在渲染之前会先判断“是否有制定的el选项”,正常的写法:el:'app',另一种用:vm.$mount('app')
$mount 可以指定一个元素,不指定元素的话,内部会默认渲染到一个内存中的节点
[JavaScript] 纯文本查看 复制代码
let vm = new Vue({
    beforeCreate(){
        console.log('---beforeCreate---')   
    },
    created(){
        console.log(this)
        console.log('---created---')
    },
    beforeMount(){
        console.log('---beforeMount---')
    },
    data(){
        return{
            msg:'hello'
        }
    }
})
vm.$mount()

虽然渲染失败了,但是走到了beforeMount这个钩子函数,它的要求是要么有个template,或者有个render函数。 把两者中一个加上:
[JavaScript] 纯文本查看 复制代码
render(){
        
    },
template:'<div>hello</div>',


验证一下我们之前没有指定el,渲染在内存中,我们把它挂载到页面中去。
[JavaScript] 纯文本查看 复制代码
vm.$mount()
console.log(vm.$el)
document.body.appendChild(vm.$el)
好处:可以把渲染好的元素插入到自己想要的节点中。
在生命周期流程图中,判读完el选项后,就会再判读是否有“指定的template选项”,是就将template编译到render函数中,没有则将el外部的HTML作为template 编译。什么叫做el外部的HTML?就是我们常用:

[Java] 纯文本查看 复制代码
<div id="app"></div>
vm.$mount('#app')

这个div就是el外部的HTML,再统一编译到render函数中。

[JavaScript] 纯文本查看 复制代码
let vm = new Vue({
    beforeCreate(){
        console.log('---beforeCreate---')   
    },
    created(){
        console.log(this)
        console.log('---created---')
    },
    render(){
        console.log('---render---')
    },
    template:'<div>hello</div>',
    beforeMount(){
        console.log('---beforeMount---')
    },
    data(){
        return{
            msg:'hello'
        }
    }
})
vm.$mount('#app')
console.log(vm.$el)
document.body.appendChild(vm.$el)

ocument.body.appendChild(vm.$el)复制代码

如果有了render就不会使用template,它内部会把template渲染成render方法,所以在挂载之前会调用render方法。优先级关系:render>template>out html
beforeMount 做的事情就是调用render方法,但是一般不会增加业务逻辑
7.mounted实例挂载到DOM上,此时可以通过DOM API获取到DOM节点,$ref属性可以访问。
[JavaScript] 纯文本查看 复制代码
 let vm = new Vue({
    beforeCreate(){
        console.log('---beforeCreate---')   
    },
    created(){
        console.log(this)
        console.log('---created---')
    },
    template:'<div>hello</div>',
    beforeMount(){
        console.log('---beforeMount---')
    },
    mounted(){
        console.log('---mounted---')
        console.log(vm.$el)
    },
    data(){
        return{
            msg:'hello'
        }
    }
})
vm.$mount('#app')



8.beforeupdatevue 更新方式是组件级别的,比如我们项目会有许多组件,在根组件中引用3个组件,其中一个组件更新重新渲染了(异步渲染),另外两个不会重新渲染。可以在这个钩子函数中,增加一些数据更新,不会导致试图多次更新。响应式数据更新时调用,发生在虚拟DOM打补丁之前。组件更新之前执行的函数。数据更新了,但是,vue(组件)对象对应的dom中的内部(innerHTML)没有变,所以叫作组件更新前。

[JavaScript] 纯文本查看 复制代码
<div id="app">{{msg}}</div>
<script>
let vm = new Vue({
    beforeCreate(){
        console.log('---beforeCreate---')   
    },
    created(){
        console.log(this)
        console.log('---created---')
    },
    beforeMount(){
        console.log('---beforeMount---')
    },
    mounted(){
        console.log('---mounted---')
        console.log(vm.$el)
    },
    beforeupdate(){
        console.log('---beforeupdate---')
    },
    data(){
        return{
            msg:'10'
        }
    }
})
vm.$mount('#app')
</script>

数据是应用到视图上才会变化。
9.updated
虚拟 DOM 重新渲染和打补丁之后调用,组件DOM已经更新,可执行依赖于DOM的操作.
这个钩子函数就不要再去更新数据,可能会发生死循环

[JavaScript] 纯文本查看 复制代码
updated(){
        this.msg= Math.random();
        console.log('---updated---')
    },


更新后会重新渲染,同时再走一边rander方法
10.beforeDestroy实例销毁之前调用。这一步,实例仍然完全可用,this仍能获取到实例这个钩子函数一般做事件的移除、清空定时器
11.destory常见的销毁方式:手动( vm.$destory()移除所有的观察者 )、移除组件、路由切换实例销毁后调用,调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。视图并不会刷新,


转自链接:https://juejin.im/post/5e81e9e16fb9a03c3c350918








欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2