Vue.js-07:第七章 - Vue 实例的生命周期
一、前言
在之前的 Vue 学习中,我们在使用 Vue 时,都会创建一个 Vue 的实例,而每个 Vue 实例在被创建时都要经过一系列的初始化过程。例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。在这个过程中,Vue 会运行一些生命周期钩子函数,而我们则可以在钩子函数中编写一些自定义方法,用以在 Vue 的整个生命周期中某些阶段实现我们特殊需求。那么,本章,我们就来了解 Vue 实例的生命周期钩子函数。
学习系列目录地址:https://www.cnblogs.com/danvic712/p/9549100.html
仓储地址:https://github.com/Lanesra712/VueTrial/blob/master/Chapter01-Rookie/hocks.html
二、干货合集
在我们使用 Vue 的时候,都会先创建一个 Vue 实例,这个实例不仅是我们挂载 Vue 框架的入口,也是 MVVM 思想中的 VM(ViewModel)。在我们使用 Vue 的整个过程中,归根结底都是在对这个 Vue 实例进行操作。因此,只有当我们了解 Vue 实例的生命周期之后,才可以更好的实现我们的业务逻辑。
在 Vue 官网的这张生命周期图示中,我们可以看到整个生命周期中包含了8个钩子函数:beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed。从字面意思我们就可以清楚的看出来,这8个钩子函数两个一组,分别对应于 Vue 实例的创建、挂载、更新、销毁,接下来,我们就根据这四个阶段,解释 Vue 实例各个阶段中的钩子函数的作用。
1、beforeCreate & created
在我们通过 new Vue() 创建了一个 Vue 实例之后,会执行 init 方法,此时只会初始化 Vue 实例所包含的一些默认的事件与生命周期函数,在这个实例还未被完全创建之前,则会执行我们的 beforeCreate 钩子函数。
在下面的例子中,我们在实例化 Vue 对象时,自定义了一个 message 属性,同时设定了一个 show 方法,现在我们来看看当实例并没有完全被创建之前,是否能够获取到我们自定义的属性与方法。
<div id="app">
{{message}}
</div> <script>
var vm = new Vue({
el: '#app',
data: {
message: 'Hello World!'
},
methods: {
show() {
console.log('执行了 show 方法');
}
},
beforeCreate() {
console.log(`Vue 实例挂载对象 el:${this.$el}`)
console.log(`Vue 实例的 data 对象:${this.$data}`)
console.log(`Vue 实例的 message 属性值:${this.message}`)
console.log(`Vue 实例的 methods 对象:${this.$options.methods}`)
this.show();
}
})
</script>

从浏览器的控制台中我们可以看到,此时,Vue 实例中的 data、methods 对象,或是我们定义的 Vue 实例的挂载点元素,在 beforeCreated 生命周期钩子函数执行时,都没有进行了初始化。
当 beforeCreated 钩子函数执行完成后,Vue 实例已经初始化完成,此时将要执行生命周期中的 created 钩子函数来监听我们对于数据的更改或是监听事件。
<div id="app">
{{message}}
</div> <script>
var vm = new Vue({
el: '#app',
data: {
message: 'Hello World!'
},
methods: {
show() {
console.log('执行了 show 方法');
}
},
created() {
console.log(`Vue 实例挂载对象 el:${this.$el}`)
console.log(`Vue 实例的 data 对象:${this.$data}`)
console.log(`Vue 实例的 message 属性值:${this.message}`)
console.log(`Vue 实例的 methods 对象:${this.$options.methods}`)
this.show();
}
})
</script>

从浏览器控制台打印出的信息可以看出,在执行 created 钩子函数的过程中,对于自定义的属性 message、自定义的方法 show 已经初始化完成,此时,整个 Vue 实例已经初始化完成。但是,对于我们的 Vue 实例的挂载点元素还没有进行初始化。也就是说,当执行完 created 之后,Vue 实例与 View(视图层)之间依旧是处于隔离的状态,初始化完成的 Vue 实例也依旧没有与 DOM 进行绑定。
2、beforeMount & mounted
当 Vue 实例执行完 beforeCreated、created 钩子函数之后,Vue 实例已经初始化完成,而 Vue 实例并没有挂载到页面的 DOM 上。在挂载到页面 DOM 元素之前,则需要执行 beforeMount 钩子函数将我们的实例绑定到模板上进行编译渲染。
<div id="app">
<h3 id="h3">{{message}}</h3>
</div> <script>
var vm = new Vue({
el: '#app',
data: {
message: 'Hello World!'
},
methods: {
show() {
console.log('执行了 show 方法');
}
},
beforeMount() {
console.log(document.getElementById('h3').innerText)
}
})
</script>

从控制台输出的信息可以看到,当执行到 beforeMount 钩子函数时,已经将模板编译完成,但是尚未挂载到页面上去。
当把编译完成的模板挂载到页面上时,则需要执行 mounted 钩子函数,在这个阶段,用户就可以看到已经渲染好的页面。
<div id="app">
<h3 id="h3">{{message}}</h3>
</div> <script>
var vm = new Vue({
el: '#app',
data: {
message: 'Hello World!'
},
methods: {
show() {
console.log('执行了 show 方法');
}
},
mounted() {
console.log(document.getElementById('h3').innerText)
}
})
</script>

这里我们可以看到,已经可以获取到差值表达式的值,即当执行到 mounted 钩子函数时,页面已经渲染完成了。
从上面的例子中可以看出,mounted 是创建 Vue 实例过程中的最后一个生命周期钩子函数,当执行完 mounted 钩子函数之后,实例已经被完成创建好,并已经渲染到页面中,此时,如果我们不对实例进行任何的操作的话,Vue 实例则不会执行 新的生命周期钩子函数。
3、beforeUpdate & updated
在执行完了 mounted 钩子函数之后,Vue 实例实际已经脱离了实例的创建阶段,进入实例的运行阶段。此时,当我们对实例的 data 进行修改时,则会触发 beforeUpdate、updated 这两个钩子函数。
<div id="app">
<h3 id="h3">{{message}}</h3>
</div> <script>
var vm = new Vue({
el: '#app',
data: {
message: 'Hello World!'
},
methods: {
show() {
console.log('执行了 show 方法');
}
},
beforeUpdate() {
console.log(`页面上的数据:${document.getElementById('h3').innerText}`)
console.log(`data 中的 message 数据:${this.message}`)
}
})
</script>

我们可以看到,当我们对 data 中的 message 属性进行修改时,在执行 beforeUpdate 钩子函数时,页面上的数据还是旧的数据,而 data 中 message 属性已经将值修改成了最新的值(这里页面上显示的为修改后的数据则是因为执行了后面的钩子函数,将修改后的数据同步渲染到了页面上)。
Vue 作为一个具有数据双向绑定特性的框架,当我们实时修改了页面元素的值之后,肯定希望页面可以同步变更数据。而在执行 beforeUpdate 钩子函数之后,我们已经在实例中修改了数据,现在只需要重新渲染到页面就可以了,这时候,则会执行 updated 钩子函数。
<div id="app">
<h3 id="h3">{{message}}</h3>
</div> <script>
var vm = new Vue({
el: '#app',
data: {
message: 'Hello World!'
},
methods: {
show() {
console.log('执行了 show 方法');
}
},
updated() {
console.log(`页面上的数据:${document.getElementById('h3').innerText}`)
console.log(`data 中的 message 数据:${this.message}`)
}
})
</script>

从控制台可以看到,当 updated 钩子函数执行的时候,页面和 data 中的数据已经完成了同步,都显示的是最新的数据。此时,整个页面数据实时变更的操作也已经完成了。
4、beforeDestroy & destroyed
既然有 Vue 实例的创建,那么在我们不需要 Vue 实例的时候就需要将这个实例进行销毁。而 beforeDestroy 以及 destroyed 钩子函数则会帮我们实现这一目的。
<div id="app">
{{message}}
</div> <script>
var vm = new Vue({
el: '#app',
data: {
message: 'Hello World!'
},
methods: {
show() {
console.log('执行了 show 方法');
}
},
beforeDestroy() {
console.log(`Vue 实例挂载对象 el:${this.$el}`)
console.log(`Vue 实例的 data 对象:${this.$data}`)
console.log(`Vue 实例的 message 属性值:${this.message}`)
console.log(`Vue 实例的 methods 对象:${this.$options.methods}`)
this.show();
},
destroyed() {
console.log(`Vue 实例挂载对象 el:${this.$el}`)
console.log(`Vue 实例的 data 对象:${this.$data}`)
console.log(`Vue 实例的 message 属性值:${this.message}`)
console.log(`Vue 实例的 methods 对象:${this.$options.methods}`)
this.show();
}
})
</script>

这里,我们手动销毁 Vue 实例,从控制台的输出内容可以看到,在 beforeDestroy 和 destroyed 钩子函数执行中,我们依旧可以获取到 Vue 实例的相关内容,可是,当我们选择更新 message 属性的值时会发现,此时,页面上显示的值并没有发生改变。原来,这里的销毁并不指代'抹去'这个 Vue 实例,而是表示将 Vue 实例与页面的 DOM 元素进行'解绑'。
三、总结
| 钩子函数 | 描述 |
|---|---|
| beforeCreate | Vue 实例进行初始化,此时实例的各个组件还没有进行初始化完成,因此不能访问到 data、computed、watch、methods 上的方法和数据,同时,Vue 实例的挂载点也没有进行初始化 |
| created | Vue 实例初始化完成,此时可以访问 data、computed、watch、methods 上的方法和数据,但是依旧没有进行 Vue 实例的挂载点初始化 |
| beforeMount | 将实例绑定到模板并进行渲染,但并不会将实例挂载到页面上 |
| mounted | 将渲染好的模板绑定到页面上,此时,Vue 实例已完全创建好 |
| beforeUpdate | 数据变更时调用,在实例数据更改之前执行任何应该发生的自定义逻辑或操作 |
| updated | 将 Vue 实例更新完成的数据重新渲染到内存中的虚拟 DOM 上,再将虚拟 DOM 应用到页面上 |
| beforeDestroy | Vue 实例进入销毁阶段,此时实例上的 data、methods、过滤器、指令等等还是处于可用的状态,还没有真正执行销毁的过程(解除与页面 DOM 元素的绑定) |
| destroyed | 实例被销毁(解除与页面 DOM 元素的绑定) |
四、参考
7、Vue.js – lifecycle hooks, the layman’s overview
Vue.js-07:第七章 - Vue 实例的生命周期的更多相关文章
- Vue.js 1.x 和 2.x 实例的生命周期
在Vue.js中,在实例化Vue之前,它们都是以HTML的文本形式存在文本编辑器中.当实例化后将经历创建.编译.销毁三个主要阶段. 以下是Vue.js 1.x 实例的生命周期图示: Vue.js 1 ...
- Vue.js 子组件的异步加载及其生命周期控制
前端开发社区的繁荣,造就了很多优秀的基于 MVVM 设计模式的框架,而组件化开发思想也越来越深入人心.这其中不得不提到 Vue.js 这个专注于 VM 层的框架. 本文主要对 Vue.js 组件化开发 ...
- 第4章-Vue.js 交互及实例的生命周期
一.学习目标 了解实例生命周期的过程 理解钩子函数的作用 掌握Vue.js过滤器的使用方法 (重点) 能够使用网络请求进行前后端交互 (重点.难点) 二.交互的基本概念 2.1.前端和后端的概念 说明 ...
- 从零开始学 Web 之 Vue.js(三)Vue实例的生命周期
大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...
- 前端MVC Vue2学习总结(二)——Vue的实例、生命周期与Vue脚手架(vue-cli)
一.Vue的实例 1.1.创建一个 Vue 的实例 每个 Vue 应用都是通过 Vue 函数创建一个新的 Vue 实例开始的: var vm = new Vue({ // 选项 }) 虽然没有完全遵循 ...
- 浅析vue实例的生命周期(生命周期钩子)
“每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听.编译模板.将实例挂载到 DOM 并在数据变化时更新 DOM 等” ,在不同的生命周期内会经历不同的钩子函数(生命周期 ...
- python 全栈开发,Day91(Vue实例的生命周期,组件间通信之中央事件总线bus,Vue Router,vue-cli 工具)
昨日内容回顾 0. 组件注意事项!!! data属性必须是一个函数! 1. 注册全局组件 Vue.component('组件名',{ template: `` }) var app = new Vue ...
- 7.Vue实例的生命周期
1.Vue实例的生命周期: 什么是生命周期:从Vue实例创建.运行.到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期! 生命周期钩子 = 生命周期函数 = 生命周期事件 2. 主要的生命 ...
- Vue.js高效前端开发 • 【Vue组件】
全部章节 >>>> 文章目录 一.Vue组件介绍 1.组件概述 2.组件使用步骤 3.实践练习 一.Vue组件使用 1.组件注册 2.组件注册语法糖 3.使用script或te ...
随机推荐
- html5中viewport与meta详解
网上解释手机浏览器是把页面放在一个虚拟的"窗口"(viewport)中,通常这个虚拟的"窗口"(viewport)比屏幕宽,这样就不用把每个网页挤到很小的窗口中 ...
- 【转载】JavaScript基础知识体系
前言 最近总是有一种感觉,对于知识没有积淀,很多时候都是忘记了哪里就去查一下,比如JS这种语言,很是浪费时间,如果能够把这些知识形成知识体系塞进大脑,做到即用即取就好了,那么就可以借助思维导图来帮助我 ...
- python取txt文件的若干行到另一个文件
取movie.txt文件的若干行到movie2.txt #取txt文件 的若干行到另一个txt f1 = open(r'F:\movie.txt','rb') f2= open(r'F:\movie2 ...
- Python常用算法(二)
1.快速排序 过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小 一般选取第一个数作为关键数据k,我们要把比k小的所有数据移到它的左面,从后往前找第一个比它 ...
- c# 如何读取web.config中的内容(ConfigurationManager)
1.web.config中写入 <appSettings> <add key="TokenQPark" value="http://localho ...
- BZOJ_1861_[Zjoi2006]Book 书架_splay
BZOJ_1861_[Zjoi2006]Book 书架_splay 题意: 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在 ...
- IE浏览器下ajax和缓存的那些事儿
项目经理最近返回了一些问题: (客户浏览器为IE11,本地360,谷歌没发现任何问题) 1.加载页面时下拉框中没有数据,关闭之后再打开出现数据: 2.数据保存之后页面没有刷新: 我也是接手别人的项目, ...
- Postman----request的body中实现数据驱动
使用场景: 一个接口多次执行,要求body中的某个参数在每次运行时都要填写不同的值,根据不同值的传入,返回不同的结果 参考示例:通过接口测试创建5条待办名称不一样的待办事项.名称格式不作要求 解决方法 ...
- koa+mysql+vue+socket.io全栈开发之数据访问篇
后端搭起大体的框架后,接着涉及到的就是如何将数据持久化的问题,也就是对数据库进行 CURD 操作. 关于数据库方案, mongodb 和 mysql 都使用过,但我选用的是 mysql,原因: 目前为 ...
- 用原生JS从零到一实现Redux架构
前言 最近利用业余时间阅读了胡子大哈写的<React小书>,从基本的原理讲解了React,Redux等等受益颇丰.眼过千遍不如手写一遍,跟着作者的思路以及参考代码可以实现基本的Demo,下 ...