大概看了下生命周期函数,记录一下
说起生命周期函数离不开这张图
用文字概括一下这张图:
new vue(): 实例化一个vue对象,然后初始化了生命周期函数,事件以及定义了createElement()
a. 初始化生命周期函数:定义了一些关于生命周期的属性(_isMounted,_isDestroyed,
_isBeingDestroyed,表示keep-alive中组件状态的inactive)
b. 初始化event:定义了$once,$on,$emit,$off
c. 定义了createElement
beforeCreate
数据初始化,定义了data,methods以及事件,劫持了数据observer,创建了watcher实例
Created: 已经可以拿到data,methods
a. 先判断有无el,若有,判断有无render,若有直接将render渲染出来,若没有,判断有 无template,若有,将template转化为render函数,若没有直接将el编译为template, 再将template转化为render
b. 若没有el,等待调用$mount(el)方法
实质都是先变成template,再转化为render
beforeMount
产生虚拟DOM,便于以后数据变化,新老DOM比较
render渲染成真实DOM,替换原来的vm.$el
Mounted:可以操作DOM
先将_isMounted属性设为true,如果页面发生更新,再判断_isMounted是否为true, _isDestroyed是否为false(确保DOM已经挂载,且页面没有销毁)
beforeUpdate
先产生新的虚拟DOM,和之前的虚拟DOM对比,利用diff计算出最小的更新范围,从而 更新render函数中的最新数据,然后将render渲染成真实DOM
Updated:可以操作DOM
虽然mounted和updated里都可以操作DOM,但如果希望在所有页面加载完毕后执行一 些操作,最好是在这两个生命周期函数里调用this.$nextTick(),执行回调函数
beforeDestroy
执行一系列销毁动作,解除各种数据引用,取消事件监听,删除子实例并将 _isDestroyed属性置为ture
Destroyed
小栗子:
var vm = new Vue({
el: '#app',
data: {
message: 'hello world'
},
template: '<div>我是模板内的{{message}}</div>',
methods: {
changeMsg () {
this.message = 'goodbye world'
}
},
beforeCreate() {
console.log('------初始化前------')
console.log(this.message)
console.log(this.$el)
},
created () {
console.log('------初始化完成------')
console.log(this.message)
console.log(this.$el)
},
beforeMount () {
console.log('------挂载前---------')
console.log(this.message)
console.log(this.$el)
},
mounted () {
console.log('------挂载完成---------')
console.log(this.message)
console.log(this.$el)
},
beforeUpdate () {
console.log('------更新前---------')
console.log(this.message)
console.log(this.$el)
},
updated() {
console.log('------更新后---------')
console.log(this.message)
console.log(this.$el)
}
})
输出:
执行beforeMounted时,$el是#app,执行完之后将template模板转化成render,再渲染出来,替换掉$el,所以输出变成了模板里的内容
this.$nextTick():
在下一次页面刷新,执行完updated()函数之后调用
<div class="app">
<div ref="msgDiv">{{msg}}</div>
<div v-if="msg1">Message got outside $nextTick: {{msg1}}</div>
<div v-if="msg2">Message got inside $nextTick: {{msg2}}</div>
<div v-if="msg3">Message got outside $nextTick: {{msg3}}</div>
<button @click="changeMsg">
Change the Message
</button>
</div>
new Vue({
el: '.app',
data: {
msg: 'Hello Vue.',
msg1: '',
msg2: '',
msg3: ''
},
methods: {
changeMsg() {
this.msg = "Hello world."
this.msg1 = this.$refs.msgDiv.innerHTML //拿到更新前的数据
this.$nextTick(() => {
this.msg2 = this.$refs.msgDiv.innerHTML //拿到更新后的数据
})
this.msg3 = this.$refs.msgDiv.innerHTML
}
}
})
输出: