目录
生命周期
生命周期图解
初始化阶段
挂载阶段
更新阶段
销毁阶段
完整代码(内含详细注释)
总结
-
生命周期
- 一个组件从创建到销毁的整个过程就是生命周期
- 分为4个阶段,8个方法
-
生命周期图解
-
初始化阶段
-
含义
-
1.new Vue() – Vue实例化(组件也是一个小的Vue实例)
-
2.Init Events & Lifecycle – 初始化事件和生命周期函数
-
3.beforeCreate – 生命周期钩子函数被执行
-
4.Init injections&reactivity – Vue内部添加data和methods等
-
5.created – 生命周期钩子函数被执行, 实例创建
-
6.接下来是编译模板阶段 –开始分析
-
7.Has el option? – 是否有el选项 – 检查要挂到哪里
-
没有. 调用$mount()方法
-
有, 继续检查template选项
-
-
-
例子
-
<script> export default { data(){ return { msg: "hello, Vue" } }, // 一. 初始化 // new Vue()以后, vue内部给实例对象添加了一些属性和方法, data和methods初始化"之前" beforeCreate(){ console.log("beforeCreate -- 执行"); console.log(this.msg); // undefined }, // data和methods初始化以后 // 场景: 网络请求, 注册全局事件 created(){ console.log("created -- 执行"); console.log(this.msg); // hello, Vue this.timer = setInterval(() => { console.log("哈哈哈"); }, 1000) } } </script>
-
-
挂载阶段
-
含义
-
1.template选项检查
-
有 - 编译template返回render渲染函数
-
无 – 编译el选项对应标签作为template(要渲染的模板)
-
- 2.虚拟DOM挂载成真实DOM之前
- 3.beforeMount – 生命周期钩子函数被执行
- 4.Create … – 把虚拟DOM和渲染的数据一并挂到真实DOM上
- 5.真实DOM挂载完毕
- 6.mounted – 生命周期钩子函数被执行
-
- 例子
-
<template> <div> <p>学习生命周期 - 看控制台打印</p> <p id="myP">{{ msg }}</p> </div> </template> <script> export default { // ...省略的为上面的初始化代码 // 二. 挂载 // 真实DOM挂载之前 // 场景: 预处理data, 不会触发updated钩子函数 beforeMount(){ console.log("beforeMount -- 执行"); console.log(document.getElementById("myP")); // null this.msg = "重新值" }, // 真实DOM挂载以后 // 场景: 挂载后真实DOM mounted(){ console.log("mounted -- 执行"); console.log(document.getElementById("myP")); // p } } </script>
-
-
-
更新阶段
-
含义
-
1.当data里数据改变, 更新DOM之前
-
2.beforeUpdate – 生命周期钩子函数被执行
-
3.Virtual DOM…… – 虚拟DOM重新渲染, 打补丁到真实DOM
-
4.updated – 生命周期钩子函数被执行
-
5.当有data数据改变 – 重复这个循环
-
-
例子
-
<template> <div> <p>学习生命周期 - 看控制台打印</p> <p id="myP">{{ msg }}</p> <ul id="myUL"> <li v-for="(val, index) in arr" :key="index"> {{ val }} </li> </ul> <button @click="arr.push(1000)">点击末尾加值</button> </div> </template> <script> export default { data(){ return { msg: "hello, Vue", arr: [5, 8, 2, 1] } }, // ...省略其他代码 // 三. 更新 // 前提: data数据改变才执行 // 更新之前 beforeUpdate(){ console.log("beforeUpdate -- 执行"); console.log(document.querySelectorAll("#myUL>li")[4]); // undefined }, // 更新之后 // 场景: 获取更新后的真实DOM updated(){ console.log("updated -- 执行"); console.log(document.querySelectorAll("#myUL>li")[4]); // li } } </script>
-
-
-
销毁阶段
-
含义
-
1.当$destroy()被调用 – 比如组件DOM被移除(例v-if)
-
2.beforeDestroy – 生命周期钩子函数被执行
-
3.拆卸数据监视器、子组件和事件侦听器
-
4.实例销毁后, 最后触发一个钩子函数
-
5.destroyed – 生命周期钩子函数被执行
-
-
-
完整代码(内含详细注释)
-
<template> <div> <h4>生命周期_1_初始化</h4> <p>{{ msg }}</p> <h4>生命周期_2_挂载</h4> <ul id="myUl"> <li v-for="(val, ind) in arr" :key="ind">{{ val }}</li> </ul> <h4>生命周期_3_更新</h4> <button @click="addFn">点击更新</button> <h4>生命周期_4_销毁</h4> </div> </template> <script> export default { data() { return { msg: "我是msg", arr: [5, 2, 1], timer: null, fn: null, }; }, methods: { addFn() { this.arr.push(0); }, }, //----------------------初始化--------------------------------- // 初始化之前 beforeCreate() { console.log("初始化之前", this.msg); }, // 初始化之后 created() { //可以操作变量 console.log("初始化之后", this.msg); this.timer = setInterval(() => { console.log(1); }, 50000); this.fn = () => { // console.log('窗口改变'); }; window.addEventListener("resize", this.fn); }, //----------------------挂载--------------------------------- // 挂载之前 beforeMount() { console.log("挂载之前", document.querySelectorAll("#myUl>li")); }, mounted() { // 拿到的为真实DOM console.log("挂载之后", document.querySelectorAll("#myUl>li")); }, //----------------------更新(数据)--------------------------------- beforeUpdate() { console.log( "更新之后", document.querySelectorAll("#myUl>li")[this.arr.length - 1] ); }, updated() { // 更新的为真实的DOM console.log( "更新之后", document.querySelectorAll("#myUl>li")[this.arr.length - 1] ); }, //----------------------销毁--------------------------------- beforeDestroy() { console.log("将要销毁此组件"); }, destroyed() { // 当前组件占用的资源全部被释放掉 // 定时器,全局事件,计时器 console.log("此组件即将被销毁"); clearInterval(this.timer); window.removeEventListener("resize", this.fn); }, // 生命周期结论(记着) // 1.在created里操作data里的变量(发送网络请求(在mounted),早发早享受) // 2.mounted里获取真实的DOM // 3.Updated里获取更新后的真实DOM // 4.destroyed // (v-if或者组件实例this.$destroyed()) -> 此组件被销毁 // 作用: // 停止计时器/定时器/全局事件(组件占有的全局资源全部释放掉) }; </script> <style> </style>
-
总结
- vue实例从创建到编译模板执行了beforeCreate / created钩子函数
- created函数触发能获取data, 不能获取真实DOM
- vue实例从创建到显示都经历beforeCreate / created / beforeMount / mounted钩子函数
- created函数里, 不能获取真实DOM
- 在mounted钩子函数里可以获取真实DOM
- 当数据发生变化并更新页面后执行updated钩子函数
- 在updated钩子函数里可以获取更新后的DOM
- 一般在beforeDestroy/destroyed里手动消除计时器/定时器/全局事件
-