细说vue的生命周期

443 阅读2分钟

经常在面试的时候面试官会问你vue的生命周期,我其实刚开始很不解vue的生命周期和做项目有什么关系,最近在学习vue的源码感觉并不是没有关系,首先你了解生命周期才会更加明白每个周期的运行机制。你可能会脱口而出,不就是beforecreated,created,beforemounted,mouted,beforeupdated,updated,beforeDestroy,destroy,这样回答我觉得面试官并不满意,但是也不能说错。


beforeCreatecreated 函数都是在实例化 Vue 的阶段,在 _init 方法中执行的,它的定义在 src/core/instance/init.js 中:

Vue.prototype._init = function (options?: Object) {
  // ...
  initLifecycle(vm)
  initEvents(vm)
  initRender(vm)
  callHook(vm, 'beforeCreate')
  initInjections(vm) // resolve injections before data/props
  initState(vm)
  initProvide(vm) // resolve provide after data/props
  callHook(vm, 'created')
  // ...
}

可以看到 beforeCreatecreated 的钩子调用是在 initState 的前后,initState 的作用是初始化 propsdatamethodswatchcomputed 等属性,那么显然 beforeCreate 的钩子函数中就不能获取到 propsdata 中定义的值,也不能调用 methods 中定义的函数,此时还是没有el选项,而在creacted里面可以拿到data,props里面的值,Beforemoted是先父组件渲染后子组件渲染,mounted是先子组件渲染后父组件渲染。在这俩个钩子函数执行的时候,并没有渲染 DOM,所以我们也不能够访问 DOM,一般来说,如果组件在加载的时候需要和后端有交互,放在这俩个钩子函数执行都可以,但是我个人建议放在created里面好一点,在created里面操作的是虚拟的dom,mounted里面是真实的dom,如果要重新操作真实的dom就应该在mouted里面。如果是需要访问 propsdata 等数据的话,就需要使用 created 钩子函数。每个子组件都是在这个钩子函数中执行 mouted 钩子函数,mounted 钩子函数的执行顺序也是先子后父。

Vue.component("demo1",{   data:function(){      return {         name:"",         age:"",         city:""       }    }, template:"<ul><li id='name'>{{name}}</li><li>{{age}}</li><li>{{city}}</li></ul>",    created:function(){       this.name="唐浩益"       this.age = "12"       this.city ="杭州"       var x = document.getElementById("name")   //第一个命令台错误       console.log(x.innerHTML);  }, mounted:function(){     var x = document.getElementById("name")    //第二个命令台输出的结果     console.log(x.innerHTML);   } }); var vm = new Vue({    el:"#example1" })

控制台输出:


以上说明在mouted阶段可以操作真实的dom,而created里面不能。

beforeUpdateupdated 的钩子函数执行时机都应该是在数据更新的时候,重新编译virtual DOM。

destroyed钩子函数在Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁,包括从 parent$children 中删掉自身,删除 watcher.destroy 钩子函数中可以做一些定时器销毁工作.