浅析Vue原理(部分源码解析)
响应式
Object.defineProperty
Object.defineProperty(obj, prop, descriptor) // 对象、属性、描述符
Object.defineProperty是es5新加的给对象属性设置描述符的方法,可以用来监听属性值的变化
var obj ={};
var _name ='张三'
Object.defineProperty(obj,'name',{
get:function () {
return _name;
},
set:function (value) {
_name=value;
}
})
调用方式:
obj.name ="里斯";
alert(obj.name);
模拟Vue响应式(data的属性代理到vm上)
var vm= {};
var data= {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
};
var i;
for (i in data){
if(data.hasOwnProperty(i)){
(function(i){ // 独立函数作用域
Object.defineProperty(vm,i,{ //将data对象的属性代理到vm
get: function () {
return data[i];
},
set:function (newVal) {
data[i]=newVal;
}
})
}(i))
}
}
vm.items[0].message='张三'
console.log(vm.items);
模板解析
- 本质:字符串
- 有逻辑: 例如v-if、v-for 等
- html模版是静态的,Vue模板是动态
- 模板必须转换成JS函数(render函数),进而转换成html渲染页面
with
//模板
function UserInfo() {
this.name = "kobe bryant";
this.age = "28";
this.gender = "boy";
}
var people=new UserInfo();
function fn(){
with(people)
{
var str = "姓名: " + name + "\n";
str += "年龄:" + age + "\n";
str += "性别:" + gender;
alert(str);
}
}
fn();
render 函数
<div class="main" :class="bindClass">
<div>{{text}}</div>
<div>hello world</div>
<div v-for="(item, index) in arr">
<p>{{item.name}}</p>
<p>{{item.value}}</p>
<p>{{index}}</p>
<p>---</p>
</div>
<div v-if="text">
{{text}}
</div>
<div v-else></div>
</div>
Vue 源码将HTML string 转换成AST
模版转换成js
with(this){
return _c( 'div',
{
/*static class*/
staticClass:"main",
/*bind class*/
class:bindClass
},
[
_c( 'div', [_v(_s(text))]),
_c('div',[_v("hello world")]),
/*这是一个v-for循环*/
_l(
(arr),
function(item,index){
return _c( 'div', //_c创建标签
[_c('p',[_v(_s(item.name))]), //_v 创建文本; _s 转换成字符串
_c('p',[_v(_s(item.value))]),
_c('p',[_v(_s(index))]),
_c('p',[_v("---")])]
)
}
),
/*这是v-if*/
(text)?_c('div',[_v(_s(text))]):_c('div',[_v("no text")])],
2
)
}
其中,this 即使Vue构造函数对象(假定为vm),item即this.item,也是data中的item
针对于上一篇的随笔:浅谈Jquery和常用框架Vue变化,我们来解析一下它的render模板
<div id="example-1">
<input v-model="title" />
<button v-on:click="add">udto list</button>
<ul>
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
</div>
模板render解析
with (this) {
// noinspection JSAnnotator
return _c('div', {attrs: {"id": "example-1"}}, [ //div
_c('input', { //input
directives: [{
name: "model",
rawName: "v-model",
value: (title),
expression: "title"
}],
domProps: {"value": (title)}, //model 往 view
on: {
"input": function ($event) {
if ($event.target.composing) return;
title = $event.target.value //view 往 model
}
}
}), _v(" "), //换行
_c('button',
{
on: {
"click": add //绑定 methods add
}
},
[
_v("udto list") //文本子节点
]
), _v(" "), //换行
_c('ul',
_l((items), function (item) { // <li v-for="item in items"> _l v-for
return _c('li',
[
_v("\n " + _s(item.message) + "\n ") //item 对应 vm.item 即 data中的item
]
)
}))
])
}
渲染
从上面例子可以看出,vue通过借鉴改造snabbdom,h函数返回的vNode,vm._c返回的也是vNode,从Vue源码中也验证了这一点,从下面Vue源码看出Vue是通过updateComponent 完成render渲染
var prevVnode = vm._vnode; //旧的vnode,initial render 第一次渲染 vnode 没有存在,装载在容器中,全部渲染
// updates
vm.$el = vm.__patch__(prevVnode, vnode); //第二次 新旧vNode对比
Vue 整个工作流程
- 将模板解析成Js,即render函数
- 监听模板,通过MVVM响应式绑定model,并完成监听
- render函数渲染成Virtual Node
- 初次渲染完成DOM节点的创建,再次渲染新旧Vittual Node对比
源码地址
https://github.com/10086XIAOZHANG/VirtualDOMDemo
浅析Vue原理(部分源码解析)的更多相关文章
- 机器学习实战(Machine Learning in Action)学习笔记————03.决策树原理、源码解析及测试
机器学习实战(Machine Learning in Action)学习笔记————03.决策树原理.源码解析及测试 关键字:决策树.python.源码解析.测试作者:米仓山下时间:2018-10-2 ...
- Spring-Session实现Session共享实现原理以及源码解析
知其然,还要知其所以然 ! 本篇介绍Spring-Session的整个实现的原理.以及对核心的源码进行简单的介绍! 实现原理介绍 实现原理这里简单说明描述: 就是当Web服务器接收到http请求后,当 ...
- Spring MVC工作原理及源码解析(三) HandlerMapping和HandlerAdapter实现原理及源码解析
1.HandlerMapping实现原理及源码解析 在前面讲解Spring MVC工作流程的时候我们说过,前端控制器收到请求后会调⽤处理器映射器(HandlerMapping),处理器映射器根据请求U ...
- Redux异步解决方案之Redux-Thunk原理及源码解析
前段时间,我们写了一篇Redux源码分析的文章,也分析了跟React连接的库React-Redux的源码实现.但是在Redux的生态中还有一个很重要的部分没有涉及到,那就是Redux的异步解决方案.本 ...
- LinkedList原理及源码解析
简介 LinkedList是一个双向线性链表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer).由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度, ...
- ORB原理与源码解析
转载: http://blog.csdn.net/luoshixian099/article/details/48523267 CSDN-勿在浮沙筑高台 没有时间重新复制代码,只能一股脑的复制,所以代 ...
- Spring核心框架 - AOP的原理及源码解析
一.AOP的体系结构 如下图所示:(引自AOP联盟) 层次3语言和开发环境:基础是指待增加对象或者目标对象:切面通常包括对于基础的增加应用:配置是指AOP体系中提供的配置环境或者编织配置,通过该配置A ...
- 【Spring】Spring IOC原理及源码解析之scope=request、session
一.容器 1. 容器 抛出一个议点:BeanFactory是IOC容器,而ApplicationContex则是Spring容器. 什么是容器?Collection和Container这两个单词都有存 ...
- RocketMQ原理及源码解析
RocketMQ原理深入: 一.定义: RocketMQ是一款分布式.队列模型的消息中间件,有以下部分组成: 1.NameServer: 一个几乎无状态的节点,可集群部署,节点之间无任何信息同步 2. ...
随机推荐
- ASP.NET内容页中访问母版页中的对象
在ASP.NET2.0开始,提供了母版页的功能.母版页由一个母版页和多个内容页构成.母版页的主要功能是为ASP.NET应用程序中的页面创建相同的布局和界面风格.母版页的使用与普通页面类似,可以在其中放 ...
- ArcSDE10.2.2使用SQL操作ST_Geometry时报ORA-28579或ORA-20006错误
ArcSDE10.2.2使用SQL操作ST_Geometry时报ORA-28579或ORA-20006错误 1.测试环境说明 ArcSDE版本:10.2.2 Oracle版本:12.1.0.1和11. ...
- Logger性能优化
最近排查线上问题,无意中发现了Logger堵塞的情况,排查的同时也做下总结,做个笔记,以防备用. 先上图,看下实际堵塞的情况 从图中可以清楚的看到标黄的都在 waiting to lock <0 ...
- MXNet 分布式环境部署
MXNet 分布式环境部署 1. MxNet 分布式介绍 先忽略吧, 回头在填上去 2. 分布式部署方法 假设有两台主机ip地址分别是xxx.xxx.xxx.114 和 xxx.xxx.xxx.111 ...
- Java 多线程使用
工作中遇到的问题,记录下解决的思路 问题: 对磁盘进行碎片化测试(比如说,磁盘空间是16G),从64K开始写文件,写满后删除一半,然后写32K 的数据,写满后删除一半...直到4K写满删除一般算是结束 ...
- Hadoop学习---Hadoop的深入学习
Hadoop生态圈 存储数据HDFS(Hadoop Distributed File System),运行在通用硬件上的分布式文件系统.具有高度容错性.高吞吐量的的特点. 处理数据MapReduce, ...
- Python 编码为什么那么蛋疼?
据说,每个做 Python 开发的都被字符编码的问题搞晕过,最常见的错误就是 UnicodeEncodeError.UnicodeDecodeError,你好像知道怎么解决,遗憾的是,错误又出现在其它 ...
- IM
一.IM技术概念 IM技术全称Instant Messaging,中文翻译"即时通讯",它是一种使人们能在网上识别在线用户并与他们实时交换消息的技术,是电子邮件发明以来迅速崛起的在 ...
- 静态路由解决双外卡,PC做路由器的实现
1,曾经医院,有两个网卡,一个内,一个外,但都有网关(192.168.1.246. 192. 168.6.1) 这样同一时候开启就会出现网络不通. 当时并没有细究原因. 这次医院信息化项目上马,我学到 ...
- Sublime Text 3中关闭记住上次打开的文件
使用UltraEdit的时候,每次安装后就得修改一堆配置,其中一项便是关闭“打开上一次未关闭的文件”,Sublime Text 2也有这么一个默认的功能,在实际使用中,这种方式确实可以较快速的访问文件 ...