解析vue中的$mount


Posted in Javascript onDecember 21, 2017

本文主要是带领大家分析$mount。

$mount所做的工作从大体来讲主要分为3步:

1.如果你的option里面没有 render 函数,那么,通过 compileToFunctions 将HTML模板编译成可以生成VNode的Render函数。

2.new 一个 Watcher 实例,触发 updateComponent 方法。

3.生成vnode,经过patch,把vnode更新到dom上。 由于篇幅有限,这里先说前两步,第三步下篇说。 好,下面具体的说。首先,我们来到 $mount 函数,如下图:

解析vue中的$mount 

我们呢可以看到,代码首先判断option里面有没有render函数,没有的话,进一步判断有没有template,没有的话就用dom元素的outerHTML。得到template以后干什么了呢?如下图。

解析vue中的$mount  

我们可以看到,调用了 compileToFunctions 将template转成render函数。这里面有两个过程:

  • 将template解析成ast语法树。
  • 通过ast语法树生成render函数。

具体的将template解析成ast语法树在本文就不说了,有时间单独开一个章节分析。好,这下我们拿到render函数了,那么接下来一步干什么了呢?没错,就开始 mountComponent 了。如下图:

解析vue中的$mount  

可以从上图看到,程序声明了一个 updateComponent 方法,这个是将要被 Watcher 实例调用的更新组件的方法,过一会分析到 Watcher 的时候将会看到。至于为什么会有个判断语句来根据条件声明 updateComponent 方法,其实从 performance 可以看出,其中一个方法是用来测试 render 和 update 性能的。好我们终于该到 Watcher 了,先看这句代码:

// we set this to vm._watcher inside the watcher's constructor
// since the watcher's initial patch may call $forceUpdate (e.g. inside child
// component's mounted hook), which relies on vm._watcher being already defined
new Watcher(vm, updateComponent, noop, null, true /* isRenderWatcher */);

我们先来分析一下注释里所说的 _watcher 是啥玩意呢?其实看看 forceupdate 的代码就知道了:

Vue.prototype.$forceUpdate = function () {
 var vm = this;
 if (vm._watcher) {
  vm._watcher.update();
 }
 };

就是调用这个vm的 _watcher 的 update 方法。用来强制更新。为什么叫强制更新呢?vue里面有判断,如果新值 == 旧值, 那么就不触发watcher更新视图了~ 所以,如果非要更新就要调用 forceupdate 来强制更新了。好,让我们来看一看传进去的参数吧:

  • vm:当前的vm实例
  • updateComponent 这个非常重要,用来在后面将vnode更新到dom上的。
  • noop 无意义的函数
  • null option选项,没有则为null
  • true 主要是用来判断是哪个watcher的。因为computed计算属性和如果你要在options里面配置watch了同样也是使用了 new Watcher ,加上这个用以区别这三者。好,我们来看看 new Watcher 都做了什么事,如下图。

解析vue中的$mount 

首先,我们看到代码有个这个判断

if (isRenderWatcher) {
 vm._watcher = this;
}

可以看到,如果声明这个watcher的上下文是用来渲染视图的,也就是说是在 mountComponent 这里调用的 new Watcher 的时候,才会把this赋值给_watcher。然后把 watcher push到 _watchers 里面,目的是等到组件销毁时顺便把watcher也销毁掉。然后就是初始化watcher的成员,代码如下:

this.deep = this.user = this.lazy = this.sync = false;<br />

接下来,就是赋值给 getter , this.getter = expOrFn 。还记得刚才传过来的 updateComponent 函数么,没错,就是这个赋值给我 getter 。然后我们就到了:

this.value = this.lazy
 ? undefined
 : this.get();

进入到 get 方法里面,我们看看到底做了什么。get代码如下图:

解析vue中的$mount 

我们可以看到,首先它执行的是 pushTarget(this) , pushTarget(this) 代码如下:

function pushTarget (_target) {
 if (Dep.target) { targetStack.push(Dep.target); }
 Dep.target = _target;
}

也就是说如果当前有 Dep.target 的话,就把target放到 targetStack 里面,如果没有的话,就设为当前的target,也就是这个watcher。 接着,就是执行了它的 getter 属性,也就是刚刚传入 updateComponent 函数。而 updateComponent 就是我们开篇提到第三步了。

总结

以上所述是小编给大家介绍的vue中的$mount,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
JSON为什么那样红为什么要用json(另有洞天)
Dec 26 Javascript
jQuery.prototype.init选择器构造函数源码思路分析
Feb 05 Javascript
使用jQuery避免鼠标双击的解决方案
Aug 21 Javascript
基于JavaScript实现类似于百度学术高级检索功能
Mar 02 Javascript
【经典源码收藏】基于jQuery的项目常见函数封装集合
Jun 07 Javascript
JS实现的自定义显示加载等待图片插件(loading.gif)
Jun 17 Javascript
js动态添加的DIV中的onclick事件简单实例
Jul 25 Javascript
模板视图和AngularJS之间冲突的解决方法
Nov 22 Javascript
微信小程序 省市区选择器实例详解(附源码下载)
Jan 05 Javascript
浅谈angularjs中响应回车事件
Apr 24 Javascript
js实现点击选项置顶动画效果
Aug 25 Javascript
原生js实现弹幕效果
Nov 29 Javascript
vue中使用refs定位dom出现undefined的解决方法
Dec 21 #Javascript
js中bool值的转换及“&amp;&amp;”、“||”、 “!!”详解
Dec 21 #Javascript
利用node实现一个批量重命名文件的函数
Dec 21 #Javascript
详解webpack3编译兼容IE8的正确姿势
Dec 21 #Javascript
利用vue开发一个所谓的数独方法实例
Dec 21 #Javascript
开发Vue树形组件的示例代码
Dec 21 #Javascript
详解使用vuex进行菜单管理
Dec 21 #Javascript
You might like
php中strstr、strrchr、substr、stristr四个函数的区别总结
2014/09/22 PHP
cakephp常见知识点汇总
2017/02/24 PHP
Laravel框架基于ajax和layer.js实现无刷新删除功能示例
2019/01/17 PHP
JavaScript操作XML实例代码(获取新闻标题并分页,并分页)
2010/05/25 Javascript
jQuery获得指定元素坐标的方法
2015/04/14 Javascript
Knockout自定义绑定创建方法
2015/12/26 Javascript
JQuery的Pager分页器实现代码
2016/05/03 Javascript
简单学习vue指令directive
2016/11/03 Javascript
JS实现侧边栏鼠标经过弹出框+缓冲效果
2017/03/29 Javascript
Agularjs妙用双向数据绑定实现手风琴效果
2017/05/26 Javascript
解决Vue页面固定滚动位置的处理办法
2017/07/13 Javascript
webpack dll打包重复问题优化的解决
2018/10/10 Javascript
如何从头实现一个node.js的koa框架
2019/06/17 Javascript
如何提升vue.js中大型数据的性能
2019/06/21 Javascript
利用node.js开发cli的完整步骤
2020/12/29 Javascript
[02:04]2014DOTA2国际邀请赛 BBC小组赛第三天总结
2014/07/12 DOTA
[52:00]2018DOTA2亚洲邀请赛 4.1 小组赛 A组加赛 LGD vs Optic
2018/04/02 DOTA
python getopt 参数处理小示例
2009/06/09 Python
Python之eval()函数危险性浅析
2014/07/03 Python
python实现12306抢票及自动邮件发送提醒付款功能
2018/03/08 Python
Python聊天室程序(基础版)
2018/04/01 Python
Jupyter notebook在mac:linux上的配置和远程访问的方法
2019/01/14 Python
详解如何在cmd命令窗口中搭建简单的python开发环境
2019/08/29 Python
Python+OpenCV 实现图片无损旋转90°且无黑边
2019/12/12 Python
Python正则表达式急速入门(小结)
2019/12/16 Python
tensorflow实现读取模型中保存的值 tf.train.NewCheckpointReader
2020/02/10 Python
Python字符串hashlib加密模块使用案例
2020/03/10 Python
Python 输出详细的异常信息(traceback)方式
2020/04/08 Python
整理HTML5移动端开发的常用触摸事件
2016/04/15 HTML / CSS
科颜氏加拿大官方网站: Kiehl’s加拿大
2016/08/16 全球购物
英国二手物品交易网站:Preloved
2017/10/06 全球购物
北京鼎普科技股份有限公司软件测试面试题
2012/04/07 面试题
大学生个人简历自我评价
2013/11/16 职场文书
24岁生日感言
2014/01/13 职场文书
四风问题党员个人整改措施
2014/10/27 职场文书
员工2014年度工作总结
2014/12/09 职场文书