示例
<body>
<div id="app">
<p>{{message}}</p>
<button @click="changeMsg">改变</button>
</div>
</body>
<script>
var vm = new Vue({
el: '#app',
data: {
message: 'hello world'
},
methods: {
changeMsg () {
this.message = 'goodbye world'
}
},
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)
}
})
</script>
1、首次加载:
数据没有修改更新时,只执行了beforeCreate,created, beforeMount, mounted。
2、传入template后的mounted
如果在new Vue实例时传入了一个template:
var vm = new Vue({
el: '#app',
data: {
message: 'hello world'
},
template: '<div>我是模板内的{{message}}</div>',
methods: {
changeMsg () {
this.message = 'goodbye world'
}
},
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)
}
})
这时候的mounted就变成了模板的div:
所以created完成后,会判断是否有el参数,如果有,看是否有template参数,如果没有,会等待调用 mount(el)方法。
确保有el后,判断当有template参数时,将template模板转换成render函数,之后再调用beforMount。
在created和beforeMount之间最主要的工作就是将模板或者el转换为render函数。
因为我们传了个template,它就直接将template转换成render函数了,再渲染为真实dom,然后在mounted用渲染出来的dom去替换原来的el。
3、updated
重回最初示例中,
且加上console.log(this.$el.innerHTML);
因为 this.el 是一个对象,其实本质就是一个指针,当我们刚console.log输出的时候,其实并没有显示内容,而当我们点击箭头去展开这个div的时候,将指针指向了当前的el,所以我们看到的才会都是改变后的el,所以用innerHTML将直观。
var vm = new Vue({
el: '#app',
data: {
message: 'hello world'
},
methods: {
changeMsg () {
this.message = 'goodbye world'
}
},
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)
console.log(this.$el.innerHTML);
},
beforeUpdate () {
console.log('------更新前----beforeUpdate-----')
console.log(this.message)
console.log(this.$el)
console.log(this.$el.innerHTML);
},
updated() {
console.log('------更新后----updated-----')
console.log(this.message)
console.log(this.$el)
console.log(this.$el.innerHTML);
}
})
当我们点击 改变按钮后
销毁阶段就不需要说了。
4、补充
在第2点时提到过
created完成后,会判断是否有el参数,如果有,看是否有template参数,如果没有,会等待调用 mount(el)方法。
确保有el后,判断当有template参数时,将template模板转换成render函数,之后再调用beforMount。
如果没有el,会等待调用 mount(el)方法。
我们删除el后:
var vm = new Vue({
data: {
message: 'hello world'
},
methods: {
changeMsg () {
this.message = 'goodbye world'
}
},
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)
console.log(this.$el.innerHTML);
},
beforeUpdate () {
console.log('------更新前----beforeUpdate-----')
console.log(this.message)
console.log(this.$el)
console.log(this.$el.innerHTML);
},
updated() {
console.log('------更新后----updated-----')
console.log(this.message)
console.log(this.$el)
console.log(this.$el.innerHTML);
}
})
只走了beforeCreate、created:
加个按钮,点击按钮,手动调用一下$mount:
<body>
<div id="app">
<p>{{message}}</p>
<button @click="changeMsg">改变</button>
<button id="mount">触发mount</button>
</div>
</body>
<script>
var m = document.getElementById('mount');
m.onclick = function(){
vm.$mount('#app');
}
//其他代码不变 同该第4点的代码的创建vue实例vm
</script>
点击按钮触发之后可以看到,生命周期继续往下走了。
这时候不知道大家是不是想起来,看到有些vue项目的main.js里面是这样的:
export default new Vue({
router,
store,
i18n,
render: h => h(App)
}).$mount('#app')
就相当于是手动调用了$mount了。
官方生命周期图如下:
参考vue生命周期