本文将对vue的生命周期进行详细的讲解,让你了解一个vue实例的诞生都经历了什么~
我在Github上创建了一个存放vue笔记的仓库,之后会陆续更新一些知识和项目中遇到的坑,有兴趣的同窗能够去看看哈(欢迎star)! vue
传送门node
const app = new Vue({ el:"#app', data:{ message:'hello,lifePeriod' }, methods:{ init(){ console.log('这是一个方法!') } } })
组件实例刚被建立,此时没法访问到 el 属性和 data 属性等..git
beforeCreate(){ console.log(`元素:${this.$el}`) //undefined console.log(`属性message:${this.message}`) //undefined console.log(`方法init:${this.init}`) //undefined }
当一个 vue 实例被建立时,他向 Vue 的响应式系统中加入了其 data 对象中能找到的全部属性.github
利用 es5 特性 Object.defineProperty,遍历 data 对象下全部属性,将其转化为 getter/setter,以便拦截对象赋值与取值操做,而后利用发布/订阅者模式,从而实现数据的双向绑定!web
因此只有当实例被建立时 data 中存在的属性才是响应式的!!!!算法
将methods 下的全部方法进行声明.app
将methods下的方法和data下的属性经过遍历和利用 es5 特性 Object.defineProperty代理到实例下.dom
this.a = this.$data.a = this.data.a; this.fn = this.$methods.fn = this.methods.fn;
组件实例建立完成,属性已绑定,但 DOM 还未生成,$el 属性还不存在!函数
created(){ console.log(`元素:${this.$el}`) //undefined console.log(`属性message:${this.message}`) //message:hey,vue-lifePeriod! console.log(`方法init:${this.init}`) //function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)} }
将模板 template 编译成 AST 树、render 函数(new Watch 将模板与数据创建联系)以及 staticRenderFns 函数(经过 diff 算法优化 dom 更新);
运行 render 方法,返回一个 vnode 对象(virtual dom)优化
模板编译/挂载以前
beforeMount(){ console.log(`元素:${(this.$el)}`) console.log(this.$el) //<div id="app">{{message}}</div> ,咱们发现此时的el还未对数据进行渲染.(虚拟dom的内容) }
模板编译/挂载以后
mounted(){ console.log(`元素:${(this.$el)}`) console.log(this.$el) //<div id="app">{{hello,vue-lifePeriod!}}</div> ,已将数据渲染到真实dom }
组件更新以前
beforeUpdate(){ console.log(this.$el.innerHTML); //hello,vue-lifePeriod ,此时,元素的真实dom内容还未改变. }
组件更新以后
updated(){ console.log(this.$el.innerHTML); //hey,vue-lifePeriod ,此时,元素的真实dom内容已经改变. }
组件销毁以前
beforeDestroy(){ console.log(this.$el) //<div id="app">{{hey,vue-lifePeriod!}}</div> console.log(`属性message:${this.message}`) //message:hey,vue-lifePeriod! console.log(`方法init:${this.init}`) //function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)} }
组件销毁以后
destroyed(){ console.log(this.$el) //<div id="app">{{hey,vue-lifePeriod!}}</div> console.log(`属性message:${this.message}`) //message:hey,vue-lifePeriod! console.log(`方法init:${this.init}`) //function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)} }
实例销毁后虽然 dom 和属性方法都还存在,但改变他们都将再也不生效!
app.message = 'hu,vue-lifePeriod';
console.log(app.message) //hey,vue-lifePeriod