何为钩子函数?先看官方文档的说法:
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
简单点来说,钩子函数就是你创建的Vue在初始化、更新数据、销毁时会被自动调用的函数。
八大钩子数分别是:
beforeCreate,created,beforeMount,mounted,beforeUpdate,updated,beforeDestory,destoryed
接下来咱们慢慢来说
附官网声明周期图
先执行一段代码:注意这里的钩子名固定,与data和methods属于平级关系,如果执行相应的方法,会输出一句话
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="http://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app"></div>
<script>
var vm=new Vue({
el: "#app",
data: {},
beforeCreate() {console.log("beforeCreate")},
created() {console.log("created")},
beforeMount() {console.log("beforeMount")},
mounted() {console.log("mounted")},
beforeUpdate() {console.log("beforeUpdate")},
updated() {console.log("updated")},
beforeDestroy() {console.log("beforeDestroy")},
destroyed() {console.log("destroyed")},
methods: {}
});
</script>
</body>
<html>
运行结果如下:
一、beforeCreate,created
beforeCreate可以简单的理解为在数据初始化的之前被调用,这时候data和methods尚未没有数据。
created可以理解为在数据初始化之后被调用,这时候data和methods已经被填充了相应的数据。
实验测试:(篇幅所限,只贴出来body中代码,head中代码没变化)
<body>
<div id="app"></div>
<script>
var vm=new Vue({
el: "#app",
data: {
msg:"在这之间" //添加msg数据
},
beforeCreate() {
console.log("this= "+this)
console.log("this.msg= "+this.msg)
console.log("this.md= "+this.md)
console.log("")
},
created() {
console.log("this= "+this)
console.log("this.msg= "+this.msg)
console.log("this.md= "+this.md)
console.log("")
},
methods: {
md: function(){}, //空方法
}
});
</script>
</body>
运行结果如下:
结果显示在beforeCreate方法与create方法之间完成了资源的注入。
二、beforeMount,mounted
上面实验已经证明Vue中数据已经注入完毕,beforeMount,mounted则是与页面渲染有关
beforeMount在页面尚未被渲染时使用,也就是Vue的数据没有传到页面。
mounted在页面渲染完成之后使用,也就是此时页面已完全取出Vue中的数据。
实验测试:
<body>
<div id="app">
<h1 id="ren">{{msg}}</h1>
</div>
<script>
var vm=new Vue({
el: "#app",
data: {
msg:"在这之间" //添加msg数据
},
beforeMount() {
let doc = document.querySelector("#ren");//查询到id名为ren的节点
console.log(doc)
console.log("")
},
mounted() {
let doc = document.querySelector("#ren");
console.log(doc)
},
});
</script>
</body>
结果如下:
此时,Vue对象中资源已注入完毕,页面也已经渲染完毕,上述四个方法在页面被加载时自动被执行
三、beforeUpdate,updated
beforeUpdate在页面更新渲染完成后,DOM树发生改变前被调用
updated在页面DOM树改变后被调用
需要注意的是如果只是改变了dom中的数据(data),未对页面造成任何影响,就不会触发beforeUpdate,updated方法。
实验证明:
<body>
<div id="app">
<h1 id="ren">
<p v-if="msg"></p>
</h1>
</div>
<script>
var vm=new Vue({
el: "#app",
data: {
msg:true //添加msg数据
},
beforeUpdate() {
let a = document.getElementById("ren");
console.log(a.childElementCount)
console.log("")
},
updated() {
let a = document.getElementById("ren");
console.log(a.childElementCount)
},
});
</script>
</body>
结果显示:
四、beforeDestory,destoryed
beforeDestory是在Vue组件销毁之前被调用
destoryed在Vue组件销毁之后被调用
这里为了搭建环境,引入了组件的概念(注意由于解析时自上而下,所以组件写在Vue对象前
实验证明:
<body>
<div id="app">
<mytest id="child" v-if="flag">
</mytest>
</div>
<script>
let myname = Vue.component('mytest', {
template: '<p>yes</p>',
beforeDestroy() {
console.log("beforeDestroy被执行")
},
destroyed() {
console.log("destroyed被执行")
},
});
var vm=new Vue({
el: "#app",
data: {
flag: true
},
components:{
"mytest" : myname,
},
});
</script>
</body>