vue 源码解析之虚拟Dom-render


Posted in Javascript onAugust 26, 2019

vue 源码解析 --虚拟Dom-render

instance/index.js
function Vue (options) {
 if (process.env.NODE_ENV !== 'production' &&
  !(this instanceof Vue)
 ) {
  warn('Vue is a constructor and should be called with the `new` keyword')
 }
 this._init(options)
}
renderMixin(Vue)

初始化先执行了 renderMixin 方法, Vue 实例化执行this._init, 执行this.init方法中有initRender()

renderMixin
installRenderHelpers( 将一些渲染的工具函数放在Vue 原型上)

Vue.prototype.$nextTick = function (fn: Function) {
  return nextTick(fn, this)
 }

仔细看这个函数, 在Vue中的官方文档上这样解释

Vue 异步执行 DOM 更新。只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部尝试对异步队列使用原生的 Promise.then MessageChannel,如果执行环境不支持,会采用 setTimeout(fn, 0)代替。

export function nextTick (cb?: Function, ctx?: Object) {
 let _resolve
 callbacks.push(() => {
  if (cb) {
   try {
    cb.call(ctx)
   } catch (e) {
    handleError(e, ctx, 'nextTick')
   }
  } else if (_resolve) {
   _resolve(ctx)
  }
 })
 if (!pending) {
  pending = true
  timerFunc()
 }
 // $flow-disable-line
 if (!cb && typeof Promise !== 'undefined') {
  return new Promise(resolve => {
   _resolve = resolve
  })
 }
}

Vue.nextTick用于延迟执行一段代码,它接受2个参数(回调函数和执行回调函数的上下文环境),如果没有提供回调函数,那么将返回promise对象。

function flushCallbacks () {
 pending = false
 const copies = callbacks.slice(0)
 callbacks.length = 0
 for (let i = 0; i < copies.length; i++) {
  copies[i]()
 }
}

这个flushCallbacks 是执行callbacks里存储的所有回调函数。

timerFunc 用来触发执行回调函数

先判断是否原生支持promise,如果支持,则利用promise来触发执行回调函数;
否则,如果支持MutationObserver,则实例化一个观察者对象,观察文本节点发生变化时,触发执行 
所有回调函数。

如果都不支持,则利用setTimeout设置延时为0。

const observer = new MutationObserver(flushCallbacks)
 const textNode = document.createTextNode(String(counter))
 observer.observe(textNode, {
  characterData: true
 })
 timerFunc = () => {
  counter = (counter + 1) % 2
  textNode.data = String(counter)
 }
 isUsingMicroTask = true

MutationObserver是一个构造器,接受一个callback参数,用来处理节点变化的回调函数,observe方法中options参数characterData:设置true,表示观察目标数据的改变

_render函数

通过执行 createElement 方法并返回的是 vnode,它是一个虚拟的 Node。

vnode = render.call(vm._renderProxy, vm.$createElement)

总结

以上所述是小编给大家介绍的vue 源码解析之虚拟Dom-render,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
JavaScript中的prototype使用说明
Apr 13 Javascript
THREE.JS入门教程(1)THREE.JS使用前了解
Jan 24 Javascript
在页面中js获取光标/鼠标的坐标及光标的像素坐标
Nov 11 Javascript
基于jquery异步传输json数据格式实例代码
Nov 23 Javascript
基于Bootstrap的Java开发问题汇总(Spring MVC)
Jan 15 Javascript
快速实现jQuery多级菜单效果
Feb 01 Javascript
layui分页效果实现代码
May 19 Javascript
js学习总结_轮播图之渐隐渐现版(实例讲解)
Jul 17 Javascript
JS实现按钮颜色切换效果
Sep 05 Javascript
微信小程序自定义prompt组件步骤详解
Jun 12 Javascript
javascript验证form表单数据的案例详解
Mar 25 Javascript
vue路由--网站导航功能详解
Mar 29 Javascript
Node.js爬虫如何获取天气和每日问候详解
Aug 26 #Javascript
vue移动端实现手机左右滑动入场动画
Jun 17 #Javascript
详解vuex数据传输的两种方式及this.$store undefined的解决办法
Aug 26 #Javascript
JS阻止事件冒泡的方法详解
Aug 26 #Javascript
express框架中使用jwt实现验证的方法
Aug 25 #Javascript
JS异步处理的进化史深入讲解
Aug 25 #Javascript
Vue源码分析之Vue实例初始化详解
Aug 25 #Javascript
You might like
php实现zip压缩文件解压缩代码分享(简单易懂)
2014/05/10 PHP
PHP实现通过get方式识别用户发送邮件的方法
2015/07/16 PHP
Swoole扩展的6种模式深入详解
2021/03/04 PHP
extjs render 用法介绍
2013/09/11 Javascript
javascript中style.left和offsetLeft的用法说明
2014/03/07 Javascript
Ext GridPanel加载完数据后进行操作示例代码
2014/06/17 Javascript
Javascript数组Array基础介绍
2016/03/13 Javascript
jQuery使用经验小技巧(推荐)
2016/05/31 Javascript
JS实现点击Radio动态更新table数据
2017/07/18 Javascript
js使用generator函数同步执行ajax任务
2017/09/05 Javascript
JS+jQuery实现注册信息的验证功能
2017/09/26 jQuery
vue实现文件上传功能
2018/08/13 Javascript
bootstrap table实现横向合并与纵向合并
2019/07/18 Javascript
js仿淘宝放大镜效果
2020/12/28 Javascript
Python对list列表结构中的值进行去重的方法总结
2016/05/07 Python
Python数据类型详解(三)元祖:tuple
2016/05/08 Python
使用python实现链表操作
2018/01/26 Python
Python3数据库操作包pymysql的操作方法
2018/07/16 Python
python三引号输出方法
2019/02/27 Python
python接口自动化(十六)--参数关联接口后传(详解)
2019/04/16 Python
SELENIUM自动化模拟键盘快捷键操作实现解析
2019/10/28 Python
Numpy之将矩阵拉成向量的实例
2019/11/30 Python
Python操作Excel把数据分给sheet
2020/05/20 Python
在PyCharm中安装PaddlePaddle的方法
2021/02/05 Python
Html5 FileReader实现即时上传图片功能实例代码
2014/09/01 HTML / CSS
阿里旅行:飞猪
2017/01/05 全球购物
德国EGOIST网店:销售畅销的设计师品牌
2017/04/18 全球购物
自动化系在校本科生求职信
2013/10/23 职场文书
多媒体编辑专业毕业生求职信
2014/06/13 职场文书
大专学生求职信
2014/07/04 职场文书
领导班子四风查摆对照检查材料思想汇报
2014/10/05 职场文书
贫困证明怎么写
2015/06/16 职场文书
MySQL中InnoDB存储引擎的锁的基本使用教程
2021/05/26 MySQL
Oracle11g R2 安装教程完整版
2021/06/04 Oracle
JavaScript展开运算符和剩余运算符的区别详解
2022/02/18 Javascript
nginx.conf配置文件结构小结
2022/04/08 Servers