先来看看官网的介绍:

主要有八个生命周期,分别是:

beforeCreate、created、beforeMount、mounted、beforeupdate、updated   、beforeDestroy和destroyed,分别对应八个不同的时期,另外还有两个activated和deactivated生命周期是对应Keep-Alive组件的

关于这八个生命周期的具体用法官网介绍的很详细了,飞机入口:点我点我 ,另外还有一张比较直观图形介绍,飞机入口:点我点我

例如:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script><title>Document</title>
</head>
<body><div id="app"><p>{{message}}</p><button @click="test1()">测试(更新操作)</button><button @click="test2()">测试(销毁操作)</button></div><script>Vue.config.productionTip=false;Vue.config.devtools=false;new Vue({el:'#app',data:{message:"Hello World!"},beforeCreate:function(){    console.log('beforeCreate');    },created:function(){         console.log('created');         },beforeMount:function(){     console.log('beforeMount');     },  mounted:function(){         console.log('mounted');         },beforeUpdate:function(){    console.log('beforeUpdate');    },updated:function(){         console.log('updated');         },beforeDestroy:function(){   console.log('beforeDestroy');   },destroyed:function(){       console.log('destroyed');       },methods:{test1:function(){this.message="Hello Vue!";},test2:function(){this.$destroy();},}})</script>
</body>
</html>

页面渲染如下:

渲染完成后控制台输出:

当点击了测试(更新操作)这个按钮后,修改了Vue实例的message值做了更新操作,此时控制台输出如下:

当我们点击测试(销毁操作)按钮时,Vue实例做了销毁操作,控制台输出如下:

对于Vue的插件(包括官方的生态)来说,绝大多数都用到了beforeCreate()这个生命周期函数,可以在实例化前混入一些属性,以vuex为例,如下:

  function applyMixin (Vue) {var version = Number(Vue.version.split('.')[0]);if (version >= 2) { Vue.mixin({ beforeCreate: vuexInit }); //如果Vue的版本大于2,则将vuexInit混入到beforeCreate生命周期函数,这样vuex就会进行初始化 } else { // override init and inject vuex init procedure // for 1.x backwards compatibility. var _init = Vue.prototype._init; Vue.prototype._init = function (options) { if ( options === void 0 ) options = {}; options.init = options.init ? [vuexInit].concat(options.init) : vuexInit; _init.call(this, options); }; }

vue-router也是的,如下:

  Vue.mixin({                                     //混入了两个生命周期,分别是beforeCreate和destroyedbeforeCreate: function beforeCreate () {if (isDef(this.$options.router)) { this._routerRoot = this; this._router = this.$options.router; this._router.init(this); Vue.util.defineReactive(this, '_route', this._router.history.current); } else { this._routerRoot = (this.$parent && this.$parent._routerRoot) || this; } registerInstance(this, this); }, destroyed: function destroyed () { registerInstance(this); } });

源码分析


生命周期的源码实现比较简单,都是通过Vue内部的一个叫callHook()的全局函数执行的,如下:

function callHook (vm, hook) {    //第2914行 vm:vue实例 hook:对应的操作名(例如:beforeCreate、created等)// #7573 disable dep collection when invoking lifecycle hooks
  pushTarget();var handlers = vm.$options[hook];           //获取生命周期函数    if (handlers) {for (var i = 0, j = handlers.length; i < j; i++) {    //遍历生命周期函数try {handlers[i].call(vm);                               //执行该函数,以vm作为上下文} catch (e) {handleError(e, vm, (hook + " hook"));}}}if (vm._hasHookEvent) {vm.$emit('hook:' + hook);}popTarget();
}

beforeCreate和created是在init()的时候执行的,如下:

Vue.prototype._init = function (options) {  //第4576行/*略*/vm._self = vm;initLifecycle(vm);initEvents(vm);initRender(vm);callHook(vm, 'beforeCreate');             //执行beforeCreate生命周期函数initInjections(vm); // resolve injections before data/props
    initState(vm);initProvide(vm); // resolve provide after data/propscallHook(vm, 'created');                  //执行created生命周期函数/*略*/};

beforeMount和mounted是在挂载的时候在mountComponent()里执行的,如下:

function mountComponent(vm, el, hydrating) {    //第2739行 挂载组件 vm:Vue实例  el:真实的DOM节点对象 /*略*/callHook(vm, 'beforeMount');                    //挂载前 执行生命周期里的beforeMount事件var updateComponent;if ("development" !== 'production' && config.performance && mark) {         //开启了性能追踪时的分支/*略*/} else {updateComponent = function () {vm._update(vm._render(), hydrating);};   }new Watcher(vm, updateComponent, noop, null, true);                       hydrating = false;if (vm.$vnode == null) {                       vm._isMounted = true;                       //设置vm._isMounted为true,表示已挂载callHook(vm, 'mounted');                    //执行生命周期里的Mount事件
    }return vm
}

beforeUpdate是在Vue原型上的_update更新时触发的,如下:

Vue.prototype._update = function (vnode, hydrating) { //第2646行var vm = this;if (vm._isMounted) {                        //如果已经挂载了,则表示已经挂载了callHook(vm, 'beforeUpdate');               //则触发beforeUpdate
    }/*略*/
}

updated是在nextTick()执行时当watcher执行完了之后触发的,如下:

function callUpdatedHooks (queue) { //第3016行var i = queue.length;while (i--) {var watcher = queue[i];var vm = watcher.vm;if (vm._watcher === watcher && vm._isMounted) { //如果当前是渲染watcher,且已经挂载了callHook(vm, 'updated');                        //则触发update生命周期函数
    }}
}

beforeDestroy和destroyed是在Vue原型的$destroy()方法里触发的,如下:

 Vue.prototype.$destroy = function () { //第2695行var vm = this;if (vm._isBeingDestroyed) {return}callHook(vm, 'beforeDestroy');        //触发beforeDestroy生命周期函数/*这里进行销毁过程*/callHook(vm, 'destroyed');            //触发destroyed生命周期函数/*略*/};
}

转载于:https://www.cnblogs.com/greatdesert/p/11062881.html

Vue.js 源码分析(九) 基础篇 生命周期详解相关推荐

  1. Vue.js 源码分析(五) 基础篇 方法 methods属性详解

    methods中定义了Vue实例的方法,官网是这样介绍的: 例如:: <!DOCTYPE html> <html lang="en"> <head&g ...

  2. linux权限源码分析,Linux基础之文件权限详解

    Linux中对于权限的制定虽然没有Windows的那么精细,但是如果你了解并掌握Linux中文件的权限知识,也可以像Windows那样对权限做到精确配置. Linux中的文件权限是什么? 如何查看Li ...

  3. Vue.js 源码分析(二十三) 指令篇 v-show指令详解

    v-show的作用是将表达式值转换为布尔值,根据该布尔值的真假来显示/隐藏切换元素,它是通过切换元素的display这个css属性值来实现的,例如: <!DOCTYPE html> < ...

  4. Spring源码分析系列-Bean的生命周期(总结篇)

    ApplicationContext和BeanFactory   BeanFactory是Spring中的顶层接口,只负责管理bean,而ApplicationContext也实现了BeanFacto ...

  5. Kafka源码分析10:副本状态机ReplicaStateMachine详解 (图解+秒懂+史上最全)

    文章很长,建议收藏起来,慢慢读! Java 高并发 发烧友社群:疯狂创客圈 奉上以下珍贵的学习资源: 免费赠送 经典图书:<Java高并发核心编程(卷1)> 面试必备 + 大厂必备 +涨薪 ...

  6. Spring源码分析之Bean的创建过程详解

    前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 Spring源码分析之BeanFactoryPostProcessor调用过程详解 本文内容: 在 ...

  7. Vue.js 源码分析—— Slots 是如何实现的

    今天主要分析 Vue.js 中常用的 Slots 功能是如何设计和实现的.本文将分为普通插槽.作用域插槽以及 Vue.js 2.6.x 版本的 v-slot 语法三部分进行讨论. 本文属于进阶内容,如 ...

  8. 从源码分析RocketMQ系列-RocketMQ消息设计详解

    1 消息存储   消息存储是RocketMQ中最为复杂和最为重要的一部分,本节将分别从RocketMQ的消息存储整体架构.PageCache与Mmap内存映射以及RocketMQ中两种不同的刷盘方式三 ...

  9. Glide源码分析3 -- 绑定Activity生命周期

    1. 概述和核心类 Glide中一个重要特性是Request可以随Activity或Fragment的onStart而resume,onStop而pause,onDestroy而clear,从而节约流 ...

最新文章

  1. PHP mysql数据迁移,【MySQL】迁移数据目录php-php教程
  2. 光纤看起来长得都一样?其实它们之间大有不同—Vecloud微云
  3. 汽车abs matlab仿真模糊pid控制
  4. spring boot 开源项目汇总
  5. php中英文手册(集成用户注释08/12/2007)
  6. mysql5.7 innodb myisam 区别_InnoDB与MyISAM的区别(高性能MySQL笔记)
  7. python的turtle画小人_Pythonturtle画图库画姓名实例
  8. “才子进销存”新一代真正基于互联网(Internet)的进销存分销管理软件
  9. 有效解决vue动态绑定多个class的官方实例语法无效的问题
  10. 怎么解决IPA processing failed错误, 用xcode 11打包
  11. vba中find用法
  12. Java 原生 PCM 格式文件转 WAV
  13. 茆诗松概率论与数理统计持续更新中...
  14. HTML实现猜数字游戏
  15. 移动端框架之mand-mobile
  16. 推荐系统实践(八)UCG 利用ltf-idf方法
  17. NOIP2022.11.23模拟赛
  18. 丢失LDF文件怎么办?
  19. 再批国标数学教材的微分定义
  20. EXCELVBA: 中国热力图 HeatMap of China

热门文章

  1. 女的喜欢OBC男的喜欢OGC的含义(转)
  2. Java 基础整理(一)
  3. syslog-ng客户端,服务器配置
  4. Cmake参数详细介绍
  5. Linux查询pg数据库账号密码,PostgreSQL登录数据库
  6. 项目疑难杂症记录(二):焦点移动不了
  7. 后台接收数组_腾讯C++后台开发面试笔试知识点参考笔记
  8. Qt实践录:一些界面设计的记录示例
  9. 使用STL去除std::vector自定义结构体重复项
  10. linux C语言调用Intel处理器CPUID指令的实例