vue2源码(九)-- 挂载阶段

这篇具有很好参考价值的文章主要介绍了vue2源码(九)-- 挂载阶段。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

原理分析

1、$mounted函数实际上调用的是mountComponent函数,该函数首先判断是否存在render函数,如果不存在,则给一个默认的渲染函数,该渲染函数会创建一个注释类型的VNode节点,然后给出警告。

2、触发beforeMount声明周期函数

3、定义updateComponent函数,该函数内部首先执行render渲染函数,得到一份最新的VNode节点树,然后执行_update方法对最新的Vnode节点和上一次的VNode节点进行对比,并更新DOM元素(即patch操作),完成一次渲染。这样子完成了挂载操作的一半工作。

4、另一半工作是开启对模板中的数据监控,当数据发生变化时,通知期其依赖进行视图更新。首先创建一个watcher实例,并将定义好的updateComponent函数作为第二个参数传入,watcher 构造函数的第二个参数支持 2 种类型,一种是数据路径,另外一种是函数。如果是数据路径,就会根据路径去读取这个数据,如果是函数,就会执行函数,一旦读取了数据或者执行了函数,就会触发数据的getter方法,getter方法会将watcher实例添加到改数据的依赖列表中,,当数据发生变化时,就会通知依赖列表进行更新,当依赖接收到通知后,就会调用第四个参数回调函数去更新视图。

换句话来说,updateComponent函数所使用到的数据都会被watcher监控,只要这些数据发生了变化,那么watcher都将会得到通知,从而掉用第四个参数回调函数去更新视图文章来源地址https://www.toymoban.com/news/detail-404944.html

源码

// hydrating是跟服务端渲染相关的
Vue.prototype.$mount = function (
  el?: string | Element,
  hydrating?: boolean
): Component {
  el = el && inBrowser ? query(el) : undefined;
  return mountComponent(this, el, hydrating);
};
// $mount实际调用的是这个函数
export function mountComponent(
  vm: Component,
  el: ?Element,
  hydrating?: boolean
): Component {
  vm.$el = el;
  // $mount最终需要的是render函数
  if (!vm.$options.render) {
    // 没有渲染函数的情况下会默认给一个渲染函数
    vm.$options.render = createEmptyVNode;
    // ...
  }
  // 触发beforeMount钩子函数
  callHook(vm, "beforeMount");

  let updateComponent;
  if (process.env.NODE_ENV !== "production" && config.performance && mark) {
    updateComponent = () => {
      // ...
      const vnode = vm._render();
      vm._update(vnode, hydrating);
    };
  } else {
    updateComponent = () => {
      vm._update(vm._render(), hydrating);
    };
  }

  // Watcher2个作用,一是初始化的时候执行回调函数,二是当vm实例中检测的数据发生变化就执行回调函数
  // 渲染watcher
  // 如果是渲染watcher,在初始化的时候会把vm._watcher赋值为watcher的实例
  new Watcher(
    vm,
    updateComponent,
    noop,
    {
      before() {
        if (vm._isMounted && !vm._isDestroyed) {
          // 如果数据发生了变化,并且组件在渲染状态并且没有销毁,触发beforeUpdate生命周期函数
          callHook(vm, "beforeUpdate");
        }
      },
    },
    true /* isRenderWatcher */
  );
  hydrating = false;

  // vm.$vnode:Vue 实例的父虚拟 Node,为null表示为根vue实例
  if (vm.$vnode == null) {
    // 根实例
    vm._isMounted = true; // 标识已经挂载
    callHook(vm, "mounted");
  }
  return vm;
}
// 把vnode渲染成真实的dom
Vue.prototype._update = function (vnode: VNode, hydrating?: boolean) {
  const vm: Component = this;
  const prevEl = vm.$el;
  const prevVnode = vm._vnode;
  const restoreActiveInstance = setActiveInstance(vm);
  vm._vnode = vnode;
  // Vue.prototype.__patch__ is injected in entry points
  // based on the rendering backend used.
  if (!prevVnode) {
    // 没有旧prevVnode就是第一次渲染
    vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */);
  } else {
    // 更新
    vm.$el = vm.__patch__(prevVnode, vnode);
  }
  restoreActiveInstance();
  // update __vue__ reference
  if (prevEl) {
    prevEl.__vue__ = null;
  }
  if (vm.$el) {
    vm.$el.__vue__ = vm;
  }
  if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) {
    vm.$parent.$el = vm.$el;
  }
};

到了这里,关于vue2源码(九)-- 挂载阶段的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Vue2.x源码系列08】Diff算法原理

    DOM是很慢的,其元素非常庞大,当我们频繁的去做 DOM更新,会产生一定的性能问题,我们可以直观感受一下 div元素包含的海量属性 在Javascript对象中, 虚拟DOM 表现为一个 Object对象(以VNode 节点作为基础的树)。并且最少包含标签名 tag 、属性 attrs 和子元素对象 children 三个

    2024年02月05日
    浏览(42)
  • 【Vue2.x源码系列07】监听器watch原理

    上一章 Vue2计算属性原理,我们介绍了计算属性是如何实现的?计算属性缓存原理?以及洋葱模型是如何应用的? 本章目标 监听器是如何实现的? 监听器选项 - immediate、deep 内部实现 在 Vue初始化实例的过程中,如果用户 options选项中存在侦听器,则初始化侦听器 watch 类型:

    2023年04月20日
    浏览(49)
  • 【Vue2.0源码学习】全局API篇-Vue中全局API分析

    与实例方法不同,实例方法是将方法挂载到 Vue 的原型上,而全局API是直接在 Vue 上挂载方法。在 Vue 中,全局API一共有12个,分别是 Vue.extend 、 Vue.nextTick 、 Vue.set 、 Vue.delete 、 Vue.directive 、 Vue.filter 、 Vue.component 、 Vue.use 、 Vue.mixin 、 Vue.observable 、 Vue.version 。这12个API中有的

    2024年02月08日
    浏览(47)
  • vue2引入Element UI组件去创建新页面的详细步骤--项目阶段2

    目录 一、Element UI介绍 Element UI的特点: 二、下载配置Element UI (零)创建vue项目 (一)下载Element UI依赖   (二)全局文件main.js中引入Element UI 三、删除多余的东西  (一)删除App.vue多余的  (二)删除多余的页面  (三)删除router路由多余的  四、新建vue页面 (一)新建

    2024年02月07日
    浏览(53)
  • Vue2-配置脚手架、分析脚手架、render函数、ref属性、props配置项、mixin配置项、scoped样式、插件

    🥔:总有一段付出了没有回报的日子 是在扎根 更多Vue知识请点击——Vue.js Vue CLI(Vue Command Line Interface)Vue脚手架,Vue官方提供的标准化开发工具(开发平台) 安装node.js——可以查看此教程 第一步:输入命令npm config set registry=http://registry.npm.taobao.org 配置镜像站,全局安装

    2024年02月12日
    浏览(68)
  • unplugin-vue-components 源码原理分析

    unplugin-vue-components 是一款按需自动导入Vue组件的库。支持 Vue2 和 Vue3,同时支持组件和指令。使用此插件库后,不再需要手动导入组件,插件会自动识别按需导入组件以及对应样式,我们只需要像全局组件那样使用即可。 当然上面说的并不严谨,此库并非全项目导入我们的组

    2023年04月16日
    浏览(40)
  • 【Vue3】2-11 : 生命周期钩子函数及原理分析

    一、组件生命周期概述 1.1 官方生命周期 1.2 钩子函数(回调函数) ▶  生命周期可划分为三个部分(- 表示执行循序): 二、实战:测试生命周期流程 >  代码  >  效果 每个组件在被创建时都要经过一系列的初始化过程 ——例如, 设置数据监听 编译模板 将实例挂载到

    2024年01月21日
    浏览(41)
  • 使用mount临时挂载出现mount error(13): Permission denied

    mount error(13): Permission denied Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) //报错信息,提示账号密码错误,其实并不是   添加 sec=ntlmssp 参数即可;中途可能需要等一些时间 mount -t cifs -o username=lisi,password=123456,sec=ntlmssp //192.168.44.10/xxx  /xxx The default in mainline kernel versions prior

    2024年02月07日
    浏览(61)
  • Linux操作之挂载(mount)

     格式化的意思即当我们创建豪逻辑分区后,需要对其指定一个文件系统,才能使用该分区。 文件系统的存在是操作系统用于明确磁盘或分区上的文件的方法和数据结构; Linux中的文件系统类型有ext2,ext3,ext4,xfs等 挂载:每个系统都有独立的inode,block,super block等信息,这

    2024年02月14日
    浏览(50)
  • vue2中将axios库挂载到Vue的原型对象上,以使其在整个Vue应用程序中可用

    通过 Vue.prototype 可以扩展Vue的原型对象,并添加自定义的属性或方法。在这种情况下, $axios 是自定义的属性名,可以根据需求进行命名。 通过 Vue.prototype.$axios = axios 这行代码,将axios库赋值给Vue的原型对象上的 $axios 属性。这样, 在Vue组件中就可以通过 this.$axios 来使用axi

    2024年01月23日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包