说明
钩子函数
特定名字的函数,在vue 生命周期某一阶段中,会执行该函数
提示:钩子函数不是程序员调用的
beforeCreate( 创建前 )
在实例初始化之后,数据观测和事件配置之前被调用,此时组件的选项对象还未创建,el 和 data 并未初始化
- 无法访问
data,methods,computed - 无法获取 dom
解释:
el:Vue 实例的el属性,即:绑定的根 DOM 元素data:Vue 实例的data属性
created ( 创建后 )
实例已经创建完成之后被调用,数据观测(data observer) 和event/watcher 事件配置 已完成
- 可以访问data、methods、watcher、events
- 无法获取 dom
- 可以执行 ajax
较常用的生命周期,因为可以调用 methods 中的方法,改变 data 中的数据,并且修改可以通过vue的响应式绑定体现在页面上,获取 computed 中的计算属性等等,通常我们可以在这里对实例进行 预处理
beforeMount
挂载开始之前被调用,相关的 render() 函数首次被调用(虚拟DOM)
实例已完成 编译模板,把data里面的数据和模板生成html,但还没有挂在到页面上。
- 无法获取 dom
(重要)mounted
挂载完成后被调用,mounted 只会执行一次。
实例已完成以下的配置:
- 将编译好的html内容 渲染 到html⻚⾯中
- 可以获取到dom
此时一般可以做一些 ajax操作
beforeUpdate
在 data 更新之前被调用,发生在虚拟DOM重新渲染和打补丁之前,可以在该钩子中进一步地更改状态,不会触发附加地重渲染过程
- 无法获取 dom
updated(更新后)
虚拟dom重新渲染后调用,若再次修改 data,会再次触发 beforeUpdate、updated,进入死循环
提示:该钩子在服务器端渲染期间不被调用
beforeDestroy(销毁前)
在实例销毁之前调用,实例仍然完全可用
- 这一步还可以用
this来获取实例, - 一般在这一步做一些重置的操作,比如:清除掉组件中的定时器 和 监听的dom事件
- 获取不到dom
destroyed(销毁后)
在实例销毁之后调用,调用后,所以的事件监听器会被移出,所有的子实例也会被销毁
- 获取不到dom
提示:该钩子在服务器端渲染期间不被调用
关于生命周期的面试题
1.什么是vue生命周期?
Vue 实例 从创建到销毁的过程,就是生命周期
从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等⼀系列过程,称之为 Vue 的生命周期。
2.vue生命周期的作用是什么?
生命周期中有多个事件钩⼦,可以在 Vue实例的过程中,更容易添加功能
3.vue生命周期总共有几个阶段?
分为8个阶段:
- 创建前/后,
- 载⼊前/后
- 更新前/后
- 销毁前/销毁后
4.第一次页面加载会触发哪几个钩⼦?
会触发:beforeCreate, created, beforeMount, mounted 。
5.DOM 渲染在 哪个周期中就已经完成?
DOM 渲染在 mounted 完成
6. 构造函数 与 data、methods
获取不到 data、不能调用 methods中函数 的钩子函数:
- beforeCreate
能获取到 data、可以调用 methods中函数 的钩子函数(beforeCreate 之后都能获取到):
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeDestroy
- destroyed
7. 钩子函数 与 DOM 对象
获取不到 DOM 对象 的钩子函数:
- beforeCreate
- created
- beforeMount
- beforeUpdate
- beforeDestroy
- destroyed
能获取到 DOM 对象 的钩子函数:
- mounted
- updated
例子
html页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
<style scoped>
#box {
/* text-align: center; */
color: #2c3e50;
/* margin-top: 60px; */
border: 1px red solid;
}
</style>
</head>
<body>
<div id="box">
{{name}} <input type="text" v-model="name"> <input type="button" value="修改name值" @click="chName">
</div>
<script>
let vue = new Vue({
el:"#box",
data:{
name:"",
},
methods:{
test(content){
console.log(content,",test()")
},
chName(){
this.name = this.name + "1"
}
},
beforeCreate(){
console.log("---------beforeCreate------------")
alert("beforeCreate")
console.log("beforeCreate name =",this.name) // 获取不到 data
var box = document.getElementById("box")
console.log("beforeCreate dom:",box) // 获取不到dom
this.test("beforeCreate") // 不能调用 methods 中的函数
},
created(){
console.log("---------created------------")
alert("created")
console.log("created name =",this.name) // 可以获取 data
var box = document.getElementById("box")
console.log("created dom:",box) // 获取不到dom
// ???????????????
this.test("created") // 可以调用 methods 中的函数
},
beforeMount(){
console.log("---------beforeMount------------")
alert("beforeMount")
console.log("beforeMount name =",this.name) // 可以获取 data
var box = document.getElementById("box")
console.log("beforeMount dom:",box) // 获取不到dom
// ?????????????????????
this.test("beforeMount") // 可以调用 methods 中的函数
},
mounted(){
// 完成渲染
console.log("---------mounted------------")
alert("mounted")
console.log("mounted name =",this.name) // 可以获取 data
var box = document.getElementById("box")
console.log("mounted dom:",box) // 可以获取到dom
this.test("mounted") // 可以调用 methods 中的函数
},
beforeUpdate(){
console.log("---------beforeUpdate------------")
alert("beforeUpdate")
console.log("beforeUpdate name =",this.name) // 可以获取 data
var box = document.getElementById("box")
console.log("beforeUpdate dom:",box) // 获取不到dom
this.test("beforeUpdate") // 可以调用 methods 中的函数
},
updated(){
console.log("---------updated------------")
alert("updated")
console.log("updated name =",this.name) // 可以获取 data
var box = document.getElementById("box")
console.log("updated dom",box) // 可以获取到dom
this.test("updated") // 可以调用 methods 中的函数
},
beforeDestroy(){
console.log("---------beforeDestroy------------")
alert("beforeDestroy")
console.log("beforeDestroy name =",this.name) // 可以获取 data
var box = document.getElementById("box")
console.log("beforeDestroy dom:",box) // 获取不到dom
this.test("beforeDestroy") // 可以调用 methods 中的函数
},
destroyed(){
console.log("---------destroyed------------")
alert("destroyed")
console.log("destroyed name =",this.name) // 可以获取 data
var box = document.getElementById("box")
console.log("destroyed dom:",box) // 获取不到dom
this.test("destroyed") // 可以调用 methods 中的函数
}
}
)
</script>
</body>
</html>
单页面
<template>
<div id="box">
{{name}} <input type="text" v-model="name"> <input type="button" value="修改name值" @click="chName">
</div>
</template>
<script>
export default
{
name: 'App',
data:function(){
return {
name:'李雷'
}
},
methods:{
test(content){
console.log(content,",test()")
},
chName(){
this.name = this.name + "1"
}
},
beforeCreate(){
console.log("---------beforeCreate------------")
alert("beforeCreate")
console.log("beforeCreate name =",this.name) // 获取不到 data
var box = document.getElementById("box")
console.log("beforeCreate dom:",box) // 获取不到dom
this.test("beforeCreate") // 不能调用 methods 中的函数
},
created(){
console.log("---------created------------")
alert("created")
console.log("created name =",this.name) // 可以获取 data
var box = document.getElementById("box")
console.log("created dom:",box) // 获取不到dom
this.test("created") // 可以调用 methods 中的函数
},
beforeMount(){
console.log("---------beforeMount------------")
alert("beforeMount")
console.log("beforeMount name =",this.name) // 可以获取 data
var box = document.getElementById("box")
console.log("beforeMount dom:",box) // 获取不到dom
this.test("beforeMount") // 可以调用 methods 中的函数
},
mounted(){
// 完成渲染
console.log("---------mounted------------")
alert("mounted")
console.log("mounted name =",this.name) // 可以获取 data
var box = document.getElementById("box")
console.log("mounted dom:",box) // 可以获取到dom
this.test("mounted") // 可以调用 methods 中的函数
},
beforeUpdate(){
console.log("---------beforeUpdate------------")
alert("beforeUpdate")
console.log("beforeUpdate name =",this.name) // 可以获取 data
var box = document.getElementById("box")
console.log("beforeUpdate dom:",box) // 获取不到dom
this.test("beforeUpdate") // 可以调用 methods 中的函数
},
updated(){
console.log("---------updated------------")
alert("updated")
console.log("updated name =",this.name) // 可以获取 data
var box = document.getElementById("box")
console.log("updated dom",box) // 可以获取到dom
this.test("updated") // 可以调用 methods 中的函数
},
beforeDestroy(){
console.log("---------beforeDestroy------------")
alert("beforeDestroy")
console.log("beforeDestroy name =",this.name) // 可以获取 data
var box = document.getElementById("box")
console.log("beforeDestroy dom:",box) // 获取不到dom
this.test("beforeDestroy") // 可以调用 methods 中的函数
},
destroyed(){
console.log("---------destroyed------------")
alert("destroyed")
console.log("destroyed name =",this.name) // 可以获取 data
var box = document.getElementById("box")
console.log("destroyed dom:",box) // 获取不到dom
this.test("destroyed") // 可以调用 methods 中的函数
}
}
</script>
<style scoped>
#box {
/* text-align: center; */
color: #2c3e50;
/* margin-top: 60px; */
border: 1px red solid;
}
</style>
图摘自:
https://www.jianshu.com/p/672e967e201c
https://www.jianshu.com/p/410b6099be69
