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 相关文章推荐
js静态方法与实例方法分析
Jul 04 Javascript
jQuery中判断一个元素是否为另一个元素的子元素(或者其本身)
Mar 21 Javascript
xml转json的js代码
Aug 28 Javascript
学习Javascript面向对象编程之封装
Feb 23 Javascript
Node.js 文件夹目录结构创建实例代码
Jul 08 Javascript
jQuery模拟完美实现经典FLASH导航动画效果【附demo源码下载】
Nov 09 Javascript
微信小程序 常见问题总结(4058,40013)及解决办法
Jan 11 Javascript
详解JavaScript中this的指向问题
Jan 20 Javascript
ES6生成器用法实例分析
Apr 10 Javascript
利用pm2部署多个node.js项目的配置教程
Oct 22 Javascript
node删除、复制文件或文件夹示例代码
Aug 13 Javascript
如何使JavaScript休眠或等待
Apr 27 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
终于听上了直流胆调频
2021/03/02 无线电
PHP 事件机制(2)
2011/03/23 PHP
jquery获取多个checkbox的值异步提交给php的方法
2015/06/24 PHP
php连接mysql数据库
2017/03/21 PHP
jquery中get和post的简单实例
2014/02/04 Javascript
JavaScript实现的in_array函数
2014/08/27 Javascript
实例解析jQuery工具函数
2016/12/01 Javascript
基于canvas的二维码邀请函生成插件
2017/02/14 Javascript
JS实现简单抖动效果
2017/06/01 Javascript
微信小程序动态添加分享数据
2017/06/14 Javascript
ES6扩展运算符的用途实例详解
2017/08/20 Javascript
详解vue+vuex+koa2开发环境搭建及示例开发
2018/01/22 Javascript
详解vuex结合localstorage动态监听storage的变化
2018/05/03 Javascript
浅谈使用mpvue开发小程序需要注意和了解的知识点
2018/05/23 Javascript
详解JavaScript原生封装ajax请求和Jquery中的ajax请求
2019/02/14 jQuery
JS删除数组指定值常用方法详解
2020/06/04 Javascript
JS运算符优先级与表达式示例详解
2020/09/04 Javascript
[02:52]2014DOTA2西雅图国际邀请赛 CIS战队巡礼
2014/07/07 DOTA
Python 提取dict转换为xml/json/table并输出的实现代码
2016/08/28 Python
Python实现压缩和解压缩ZIP文件的方法分析
2017/09/28 Python
python调用c++传递数组的实例
2019/02/13 Python
Python实现EXCEL表格的排序功能示例
2019/06/25 Python
简单了解Python matplotlib线的属性
2019/06/29 Python
基于Python实现签到脚本过程解析
2019/10/25 Python
Django密码存储策略分析
2020/01/09 Python
详解Python之Scrapy爬虫教程NBA球员数据存放到Mysql数据库
2021/01/24 Python
HTML5 Canvas鼠标与键盘事件demo示例
2013/07/04 HTML / CSS
在线购买廉价折扣书籍和小说:BookOutlet.com
2018/02/19 全球购物
重新定义牛仔布,100美元以下:Warp + Weft
2018/07/25 全球购物
基层党建工作汇报材料
2014/08/15 职场文书
小学教师学习党的群众路线教育实践活动心得体会
2014/10/31 职场文书
物业工程部经理岗位职责
2015/04/09 职场文书
python Tkinter的简单入门教程
2021/04/11 Python
英镑符号 £
2022/02/17 杂记
Mysql外键约束的创建与删除的使用
2022/03/03 MySQL
详细聊一聊mysql的树形结构存储以及查询
2022/04/05 MySQL