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 相关文章推荐
做网页的一些技巧
Feb 01 Javascript
JQuery 学习笔记 element属性控制
Jul 23 Javascript
js 获取时间间隔实现代码
May 12 Javascript
jquery解决客户端跨域访问问题
Jan 06 Javascript
javascript日期格式化方法汇总
Oct 04 Javascript
JavaScript实现的背景自动变色代码
Oct 17 Javascript
javascript面向对象程序设计高级特性经典教程(值得收藏)
May 19 Javascript
jquery仿ps颜色拾取功能
Mar 08 Javascript
利用jQuery解析获取JSON数据
Apr 08 jQuery
Angular客户端请求Rest服务跨域问题的解决方法
Sep 19 Javascript
checkbox在vue中的用法小结
Nov 13 Javascript
Vue Object.defineProperty及ProxyVue实现双向数据绑定
Sep 02 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之apc
2013/05/15 PHP
php 下 html5 XHR2 + FormData + File API 上传文件操作实例分析
2020/02/28 PHP
超强的IE背景图片闪烁(抖动)的解决办法
2007/09/09 Javascript
一些javascript一些题目的解析
2010/12/25 Javascript
网页右侧悬浮滚动在线qq客服代码示例
2014/04/28 Javascript
javascript生成随机数的方法
2014/05/16 Javascript
JavaScript实现定时隐藏与显示图片的方法
2015/08/06 Javascript
jQuery如何防止Ajax重复提交
2016/10/14 Javascript
bootstrap模态框跳转到当前模板页面 框消失了而背景存在问题的解决方法
2020/11/30 Javascript
使用Angular缓存父页面数据的方法
2017/01/03 Javascript
ionic2打包android时gradle无法下载的解决方法
2017/04/05 Javascript
JS闭包可被利用的常见场景小结
2017/04/09 Javascript
JS全角与半角转化实例(分享)
2017/07/04 Javascript
angular 组件通信的几种实现方式
2018/07/13 Javascript
关于自定义Egg.js的请求级别日志详解
2018/12/12 Javascript
Vue 实现v-for循环的时候更改 class的样式名称
2020/07/17 Javascript
简单谈谈Python中的闭包
2016/11/30 Python
Python使用遗传算法解决最大流问题
2018/01/29 Python
一个简单的python爬虫程序 爬取豆瓣热度Top100以内的电影信息
2018/04/17 Python
pandas计算最大连续间隔的方法
2019/07/04 Python
django url到views参数传递的实例
2019/07/19 Python
tensorflow 实现打印pb模型的所有节点
2020/01/23 Python
利用Python中的Xpath实现一个在线汇率转换器
2020/09/09 Python
GUESS盖尔斯法国官网:美国时尚品牌
2016/09/23 全球购物
递归计算如下递归函数的值(斐波拉契)
2012/02/04 面试题
机电一体化自荐信
2013/12/10 职场文书
先进集体获奖感言
2014/02/13 职场文书
群众路线剖析材料范文
2014/10/09 职场文书
交通事故赔偿协议书
2014/10/16 职场文书
实习推荐信格式模板
2015/03/27 职场文书
孟佩杰观后感
2015/06/17 职场文书
大学生读书笔记范文
2015/07/01 职场文书
2016年暑假家长对孩子评语
2015/12/01 职场文书
抖音短视频(douyin)去水印工具的实现代码
2021/03/30 Javascript
Go语言中的UTF-8实现
2021/04/26 Golang
MySQL 原理优化之Group By的优化技巧
2022/08/14 MySQL