最近在写业务的时候,老是会遇到一些和vue的生命周期相关的问题,好比: 你用ajax请求数据,而后将数据props到子组件的时候,由于ajax是异步的,而后会发生没有数据。而后查找缘由仍是本身对这个东西理解不够深刻。html
什么是生命周期函数?vue
好比:react
mounted: function() {
}
// 或者
mounted() {
}
复制代码
错误的形式:ajax
mounted:() => {
}
复制代码
实例初始化——new Vue()
bash
数据观测——在vue的响应式系统中加入data对象中全部数据,这边涉及到vue的双向绑定,能够看官方文档上的这篇深度响应式原理 深度响应式原理app
暴露属性和方法——就是vue实例自带的一些属性和方法,咱们能够看一个官网的例子,例子中带$的属性和方法就是vue实例自带的,能够和用户定义的区分开来异步
var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})
vm.$data === data // => true
vm.$el === document.getElementById('example') // => true
// $watch 是一个实例方法
vm.$watch('a', function (newValue, oldValue) {
// 这个回调将在 `vm.a` 改变后调用
})
复制代码
// 有el属性的状况下
new Vue({
el: '#app',
beforeCreate: function() {
console.log('调用了beforeCreate')
},
created: function() {
console.log('调用了created')
},
beforeMount: function() {
console.log('调用了beforeMount')
},
mounted: function() {
console.log('调用了mounted')
}
})
// 输出结果
// 调用了beforeCreate
// 调用了created
// 调用了beforeMount
// 调用了mounted
复制代码
// 在没有el属性的状况下,没有vm.$mount
new Vue({
beforeCreate: function() {
console.log('调用了beforeCreate')
},
created: function() {
console.log('调用了created')
},
beforeMount: function() {
console.log('调用了beforeMount')
},
mounted: function() {
console.log('调用了mounted')
}
})
// 输出结果
// 调用了beforeCreate
// 调用了created
复制代码
// 在没有el属性的状况下,可是有vm.$mount方法
var vm = new Vue({
beforeCreate: function() {
console.log('调用了beforeCreate')
},
created: function() {
console.log('调用了created')
},
beforeMount: function() {
console.log('调用了beforeMount')
},
mounted: function() {
console.log('调用了mounted')
}
})
vm.$mount('#app')
// 输出结果
// 调用了beforeCreate
// 调用了created
// 调用了beforeMount
// 调用了mounted
复制代码
这里面分三种状况:ide
一、在实例内部有template属性的时候,直接用内部的,而后调用render函数去渲染。 二、在实例内部没有找到template,就调用外部的html。实例内部的template属性比外部的优先级高。 三、要是前二者都不知足,那么就抛出错误。函数
咱们来看如下几个例子:ui
new Vue({
el: '#app',
template: '<div id="app">hello world</div>'
})
//页面上渲染出了hello world
复制代码
<div id="app">hello world</div>
new Vue({
el: '#app'
})
// 页面上渲染出了hello world
复制代码
//二者都存在的时候
<div id="app">hello world2</div>
new Vue({
el: '#app',
template: '<div id="app">hello world1</div>'
})
// 页面上渲染出了hello world1
复制代码
从上述的例子能够看出内部的优先外部的。
一、为何el属性的判断在template以前? 由于el是一个选择器,好比上述例子中咱们用到的最多的是id选择器app,vue实例须要用这个el去template中寻找对应的。
二、实际上,vue实例中还有一种render选项,咱们能够从文档上看一下他的用法:
new Vue({
el: '#app',
render() {
return (...)
}
})
复制代码
三、上述三者的渲染优先级:render函数 > template属性 > 外部html
四、vue编译过程——把tempalte编译成render函数的过程。
咱们先来看一个例子:
<div id="app">
<p>{{message}}</p>
</div>
new Vue({
el: '#app',
data: {
message: 1
},
beforeMount: function() {
console.log('调用了beforeMount');
console.log(this.message)
console.log(this.$el)
},
mounted: function() {
console.log('调用了mounted');
console.log(this.message)
console.log(this.$el)
}
})
// 输出的结果:
// 调用了beforeMount
// 1
// <div>
// </div>
// 调用了mounted
// 1
// <div id="app">
// <p>1</p>
// </div>
复制代码
建立vue实例的$el,而后用它替代el属性。
这个过程当中,咱们会发现,当一个数据发生改变时,你的视图也将随之改变,整个更新的过程是:数据改变——致使虚拟DOM的改变——调用这两个生命钩子去改变视图
// 没绑定的状况
var vm = new Vue({
el: '#app',
template: '<div id="app"></div>',
beforeUpdate: function() {
console.log('调用了beforeUpdate')
},
updated: function() {
console.log('调用了uodated')
},
data: {
a: 1
}
})
vm.a = 2
//这种状况在控制台中是什么都不会输出的。
复制代码
var vm = new Vue({
el: '#app',
template: '<div id="app">{{a}}</div>',
beforeUpdate: function() {
console.log('调用了beforeUpdate')
},
updated: function() {
console.log('调用了uodated')
},
data: {
a: 1
}
})
vm.a = 2
// 输出结果:
// 调用了beforeUpdate
// 调用了uodated
复制代码
在beferoDestory生命钩子调用以前,全部实例均可以用,可是当调用后,Vue 实例指示的全部东西都会解绑定,全部的事件监听器会被移除,全部的子实例也会被销毁。
let vm = new Vue({
el: '#app',
data: {
message: 1
},
template: '<div id="app"><p>{{message}}</p></div>',
beforeCreate() {
console.log('调用了beforeCreate')
console.log(this.message)
console.log(this.$el)
},
created() {
console.log('调用了created')
console.log(this.message)
console.log(this.$el)
},
beforeMount() {
console.log('调用了beforeMount')
console.log(this.message)
console.log(this.$el)
},
mounted() {
console.log('调用了mounted')
console.log(this.message)
console.log(this.$el)
},
beforeUpdate() {
console.log('调用了beforeUpdate')
console.log(this.message)
console.log(this.$el)
},
updated() {
console.log('调用了updated')
console.log(this.message)
console.log(this.$el)
},
beforeDestory() {
console.log('调用了beforeDestory')
console.log(this.message)
console.log(this.$el)
},
destoryed() {
console.log('调用了Destoryed')
console.log(this.message)
console.log(this.$el)
}
})
vm.message = 2
复制代码
// 调用了beforeCreate
// undefined
// undefined
// 调用了created
// 1
// undefined
// 调用了beforeMount
// 1
// <div></div>
// 调用了mounted
// 1
// <div id="app"><p>1</p></div>
// 调用了beforeUpdate
// 2
// <div id="app"><p>2</p></div>
// 调用了updated
// 2
// <div id="app"><p>2</p></div>
复制代码