每个vue实例在被创建之前都要经过一系列的初始化过程,这个过程就是vue的生命周期。详细来说,就是Vue实例从开始创建,初始化数据,编译模板,挂在dom->渲染,更新->渲染,卸载等一系列过程,我们称这是vue的生命周期,各个阶段有相对应的事件钩子。
代码:
let vm = new Vue({ // 当前这个实例他的父亲是谁 儿子谁 有一套 beforeCreate(){ console.log(this); console.log('---beforeCreate---'); }, data(){ return{ msg:'hello' } } }) 复制代码
从打印出来的this,可以看到此时发布订阅 emit等vue原生API已经初始化完成。但是不能访问到data,computed,watch,methods上的方法和数据。这个钩子函数不能做业务逻辑,一般情况下这个钩子函数可以做的事情:在每个组建中增加一些特定的属性,例如混合。
这个实例已经实现了数据劫持,把方法、计算属性 也都挂载到了实例,不能获取到真实的dom元素。不能访问到 ref属性内容未空数组。 这个钩子函数可以发送axios请求把请求回来的数据保存到data中。
let vm = new Vue({ beforeCreate(){ console.log(this); console.log('---beforeCreate---'); }, created(){ console.log(this); console.log('---created---'); debugger; }, data(){ return{ msg:'hello' } } }) 复制代码
接下来就是渲染,但是在渲染之前会先判断“是否有制定的el选项”,正常的写法:el:'app',另一种用:vm.$mount('app')
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函数。 把两者中一个加上:
render(){ }, template:'<div>hello</div>', 复制代码
验证一下我们之前没有指定el,渲染在内存中,我们把它挂载到页面中去。
vm.$mount() console.log(vm.$el) document.body.appendChild(vm.$el) 复制代码好处:可以把渲染好的元素插入到自己想要的节点中。
在生命周期流程图中,判读完el选项后,就会再判读是否有“指定的template选项”,是就将template编译到render函数中,没有则将el外部的HTML作为template 编译。 什么叫做el外部的HTML?就是我们常用:
<div id="app"></div> vm.$mount('#app') 复制代码
这个div就是el外部的HTML,再统一编译到render函数中。
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) 复制代码
优先级关系:render>template>out html
beforeMount 做的事情就是调用render方法,但是一般不会增加业务逻辑
实例挂载到DOM上,此时可以通过DOM API获取到DOM节点,$ref属性可以访问。
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') 复制代码
可以在这个钩子函数中,增加一些数据更新,不会导致试图多次更新。 响应式数据更新时调用,发生在虚拟DOM打补丁之前。 组件更新之前执行的函数。 数据更新了,但是,vue(组件)对象对应的dom中的内部(innerHTML)没有变,所以叫作组件更新前。
<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> 复制代码数据是应用到视图上才会变化。
虚拟 DOM 重新渲染和打补丁之后调用,组件DOM已经更新,可执行依赖于DOM的操作.
updated(){ this.msg= Math.random(); console.log('---updated---') }, 复制代码
实例销毁之前调用。这一步,实例仍然完全可用,this仍能获取到实例 这个钩子函数一般做事件的移除、清空定时器
常见的销毁方式:手动( vm.$destory()移除所有的观察者 )、移除组件、路由切换 实例销毁后调用,调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。视图并不会刷新,