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 变量命名规则
Sep 23 Javascript
jquery隔行换色效果实现方法
Jan 15 Javascript
纯HTML5制作围住神经猫游戏-附源码下载
Aug 23 Javascript
javascript倒计时效果实现
Nov 12 Javascript
归纳下js面向对象的几种常见写法总结
Aug 24 Javascript
基于JS组件实现拖动滑块验证功能(代码分享)
Nov 18 Javascript
vue实现全选和反选功能
Aug 31 Javascript
vue.js todolist实现代码
Oct 29 Javascript
微信小程序如何像vue一样在动态绑定类名
Apr 17 Javascript
vue的传参方式汇总和router使用技巧
May 22 Javascript
es6 filter() 数组过滤方法总结
Apr 03 Javascript
Electron vue的使用教程图文详解
Jul 05 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字符转义相关函数小结(php下的转义字符串)
2007/04/12 PHP
PHP 在线翻译函数代码
2009/05/07 PHP
PHP 类相关函数的使用详解
2013/05/10 PHP
PHP中echo和print的区别
2014/08/28 PHP
PHP也能干大事之PHP中的编码解码详解
2015/04/20 PHP
php根据日期或时间戳获取星座信息和生肖等信息
2015/10/20 PHP
AppBaseJs 类库 网上常用的javascript函数及其他js类库写的
2010/03/04 Javascript
javascript开发随笔一 preventDefault的必要
2011/11/25 Javascript
浅析JavaScript中两种类型的全局对象/函数
2013/12/05 Javascript
jQuery实现table隔行换色和鼠标经过变色的两种方法
2014/06/15 Javascript
javascript常用代码段搜集
2014/12/04 Javascript
javaScript的函数对象的声明详解
2015/02/06 Javascript
详解Bootstrap glyphicons字体图标
2016/01/04 Javascript
jQuery内容筛选选择器实例代码
2017/02/06 Javascript
canvas时钟效果
2017/02/16 Javascript
javascript 中Cookie读、写与删除操作
2017/03/29 Javascript
ES6学习之变量的两种命名方法示例
2017/07/18 Javascript
vue中实现图片和文件上传的示例代码
2018/03/16 Javascript
js实现贪吃蛇小游戏
2019/10/29 Javascript
简单分析Python中用fork()函数生成的子进程
2015/05/04 Python
Python2.x版本中cmp()方法的使用教程
2015/05/14 Python
python中如何使用朴素贝叶斯算法
2017/04/06 Python
Python3 XML 获取雅虎天气的实现方法
2018/02/01 Python
numpy返回array中元素的index方法
2018/06/27 Python
对python 合并 累加两个dict的实例详解
2019/01/21 Python
pandas 时间格式转换的实现
2019/07/06 Python
django-rest-swagger对API接口注释的方法
2019/08/29 Python
Tensorflow之梯度裁剪的实现示例
2020/03/08 Python
Python日志处理模块logging用法解析
2020/05/19 Python
日常奢侈品,轻松购物:Verishop
2019/08/20 全球购物
《宿建德江》教学反思
2014/04/23 职场文书
村级个人对照检查材料
2014/08/22 职场文书
解放思想大讨论活动总结
2015/05/09 职场文书
市级三好生竞选稿
2015/11/21 职场文书
简单聊聊Vue中的计算属性和属性侦听
2021/10/05 Vue.js
聊聊mysql都有哪几种分区方式
2022/04/13 MySQL