• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • dedecms
  • ecshop
  • z-blog
  • UcHome
  • UCenter
  • drupal
  • WordPress
  • 帝国cms
  • phpcms
  • 动易cms
  • phpwind
  • discuz
  • 科汛cms
  • 风讯cms
  • 建站教程
  • 运营技巧
您的位置:首页 > CMS教程 >建站教程 > 浅析vue中的生命周期钩子mounted

浅析vue中的生命周期钩子mounted

作者:站长图库 字体:[增加 减小] 来源:互联网

站长图库向大家介绍了vue生命周期,vue钩子mounted等相关知识,希望对您有所帮助

本篇文章带大家了解一下vue中的生命周期钩子,介绍一下vue中的mounted钩子,希望对大家有所帮助!


浅析vue中的生命周期钩子mounted


注:阅读本文需要对vue的patch流程有较清晰的理解,如果不清楚patch流程,建议先了解清楚这个流程再阅读本文,否则可能会感觉云里雾里。

聊之前我们先看一个场景

<div id="app">    <aC />    <bC /></div>

如上所示,App.vue文件里面有两个子组件,互为兄弟关系

组件里面自各有created和mounted两个生命周期钩子,a表示组件名 C是created的缩写

// a组件created() {    console.log('aC')  },mounted() {  debugger  console.log('aM')}, // b组件created() {    console.log('bC')  },mounted() {  debugger  console.log('bM')},

请问打印顺序是什么?各位读者可以先脑补一下,后面看看对不对。

如果对vue patch流程比较熟悉的读者,可能会认为顺序是aC→aM→bC→BM,也就是a组件先创建,再挂载,然后到b组件重复以上流程。因为从patch的方法里面可以知道,组件created后,再走到insert进父容器的过程,是一个同步的流程,只有这个流程走完后,才会遍历到b组件,走b组件的渲染流程。

实际上浏览器打印出来的顺序是aC→bC→aM→bM,也就是两个created先执行,才到mounted执行,和上面的分析相悖。这里先说原因,子组件从created到insert进父容器的过程还是同步的,但是insert进父容器后,也可以理解为子组件mounted,并没有马上调用mounted生命周期钩子。下面从源码角度分析一下:

先大概回顾一下子组件渲染流程,patch函数调用createElm创建真实element,createElm里面通过createComponent判断当前vnode是否组件vnode,是则进入组件渲染流程

function createComponent (vnode, insertedVnodeQueue, parentElm, refElm) {  var i = vnode.data;  if (isDef(i)) {    var isReactivated = isDef(vnode.componentInstance) && i.keepAlive;    if (isDef(i = i.hook) && isDef(i = i.init)) {      i(vnode, false /* hydrating */);    }    if (isDef(vnode.componentInstance)) {      initComponent(vnode, insertedVnodeQueue);              // 最终组件创建完后会走到这里 把组件对应的el插入到父节点      insert(parentElm, vnode.elm, refElm);      if (isTrue(isReactivated)) {        reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm);      }      return true    }  }}

createComponent里面就把组件对应的el插入到父节点,最后会返回到patch调用栈,调用

invokeInsertHook(vnode, insertedVnodeQueue, isInitialPatch);

因为子组件有vnode.parent所以会走一个分支,但是我们也看看第二个分支调用的insert是什么

function invokeInsertHook (vnode, queue, initial) {  // delay insert hooks for component root nodes, invoke them after the  // element is really inserted  if (isTrue(initial) && isDef(vnode.parent)) {    vnode.parent.data.pendingInsert = queue;  } else {    for (var i = 0; i < queue.length; ++i) {      queue[i].data.hook.insert(queue[i]);    }  }}

这个insert是挂在vnode.data.hook上,在组件创建过程中,createComponent方法里面有一个调用

installComponentHooks,在这里把insert钩子注入了。这个方法实际定义在componentVNodeHooks对象里面,可以看到这个insert里面调用了callHook(componentInstance, 'mounted'),这里实际上就是调用子组件的mounted生命周期。

insert: function insert (vnode) {  var context = vnode.context;  var componentInstance = vnode.componentInstance;  if (!componentInstance._isMounted) {    componentInstance._isMounted = true;    callHook(componentInstance, 'mounted');  }  if (vnode.data.keepAlive) {    if (context._isMounted) {      // vue-router#1212      // During updates, a kept-alive component's child components may      // change, so directly walking the tree here may call activated hooks      // on incorrect children. Instead we push them into a queue which will      // be processed after the whole patch process ended.      queueActivatedComponent(componentInstance);    } else {      activateChildComponent(componentInstance, true /* direct */);    }  }},

再来看看这个方法,子组件走第一个分支,仅仅执行了一行代码vnode.parent.data.pendingInsert = queue , 这个queue实际是在patch 开始时候,定义的insertedVnodeQueue。这里的逻辑就是把当前的insertedVnodeQueue,挂在parent的vnode data的pendingInsert上。

function invokeInsertHook (vnode, queue, initial) {  // delay insert hooks for component root nodes, invoke them after the  // element is really inserted  if (isTrue(initial) && isDef(vnode.parent)) {    vnode.parent.data.pendingInsert = queue;  } else {    for (var i = 0; i < queue.length; ++i) {      queue[i].data.hook.insert(queue[i]);    }  }}// 在patch 开始时候 定义了insertedVnodeQueue为一个空数组var insertedVnodeQueue = [];

源码里面再搜索insertedVnodeQueue ,可以看到有这样一段逻辑,initComponent还是在createComponent里面调用的

function initComponent (vnode, insertedVnodeQueue) {  if (isDef(vnode.data.pendingInsert)) {    insertedVnodeQueue.push.apply(insertedVnodeQueue, vnode.data.pendingInsert);    vnode.data.pendingInsert = null;  }  vnode.elm = vnode.componentInstance.$el;  if (isPatchable(vnode)) {          // ??注意这个方法     invokeCreateHooks(vnode, insertedVnodeQueue);    setScope(vnode);  } else&n
  


 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 浅析vue中的生命周期钩子mounted

相关文章

  • 浅谈小程序跨页面之间通信的几种方式
  • 踩坑分享:Laravel集成phpCAS过程
  • 提高mysql千万级大数据SQL查询优化30条经验(Mysql索引优化注意)
  • 支付宝企业账户转账个人账户PHP接口代码
  • 解决并分析Incorrect datetime value报错问题
  • AI制作数字通道效果
  • Alexa优化技巧大全
  • 帝国CMS灵动标签去除重复标题信息
  • 苹果CMSv10批量删除视频数据方法
  • jQuery表单插件jquery.form.js

文章分类

  • dedecms
  • ecshop
  • z-blog
  • UcHome
  • UCenter
  • drupal
  • WordPress
  • 帝国cms
  • phpcms
  • 动易cms
  • phpwind
  • discuz
  • 科汛cms
  • 风讯cms
  • 建站教程
  • 运营技巧

最近更新的内容

    • Photoshop制作金属嵌钻图案效果的字效
    • WordPress官网429无法打开导致不能更新版本及插件问题解决方法
    • Laravel隐藏index.php的方法
    • 在PHP中实现加密的这三种方法,你会选择哪个?
    • Photoshop制作折纸风格的短信软件图标
    • Illustrator使用混合和透明度制作发光按钮
    • 解决thinkphp5中图片处理中遇到的问题
    • Photoshop调出美女照片梦幻蓝色调教程
    • Thinkphp5整合phpsocketio过程亲自踩的坑!
    • PhotoShop制作魔幻霓虹火焰字效果的教程

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有