响应式

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); 

模板解析

  1. 本质:字符串
  2. 有逻辑: 例如v-if、v-for 等
  3. html模版是静态的,Vue模板是动态
  4. 模板必须转换成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 整个工作流程

  1.  将模板解析成Js,即render函数
  2. 监听模板,通过MVVM响应式绑定model,并完成监听
  3. render函数渲染成Virtual Node
  4. 初次渲染完成DOM节点的创建,再次渲染新旧Vittual Node对比

源码地址

https://github.com/10086XIAOZHANG/VirtualDOMDemo  

浅析Vue原理(部分源码解析)的更多相关文章

  1. 机器学习实战(Machine Learning in Action)学习笔记————03.决策树原理、源码解析及测试

    机器学习实战(Machine Learning in Action)学习笔记————03.决策树原理.源码解析及测试 关键字:决策树.python.源码解析.测试作者:米仓山下时间:2018-10-2 ...

  2. Spring-Session实现Session共享实现原理以及源码解析

    知其然,还要知其所以然 ! 本篇介绍Spring-Session的整个实现的原理.以及对核心的源码进行简单的介绍! 实现原理介绍 实现原理这里简单说明描述: 就是当Web服务器接收到http请求后,当 ...

  3. Spring MVC工作原理及源码解析(三) HandlerMapping和HandlerAdapter实现原理及源码解析

    1.HandlerMapping实现原理及源码解析 在前面讲解Spring MVC工作流程的时候我们说过,前端控制器收到请求后会调⽤处理器映射器(HandlerMapping),处理器映射器根据请求U ...

  4. Redux异步解决方案之Redux-Thunk原理及源码解析

    前段时间,我们写了一篇Redux源码分析的文章,也分析了跟React连接的库React-Redux的源码实现.但是在Redux的生态中还有一个很重要的部分没有涉及到,那就是Redux的异步解决方案.本 ...

  5. LinkedList原理及源码解析

    简介 LinkedList是一个双向线性链表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer).由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度, ...

  6. ORB原理与源码解析

    转载: http://blog.csdn.net/luoshixian099/article/details/48523267 CSDN-勿在浮沙筑高台 没有时间重新复制代码,只能一股脑的复制,所以代 ...

  7. Spring核心框架 - AOP的原理及源码解析

    一.AOP的体系结构 如下图所示:(引自AOP联盟) 层次3语言和开发环境:基础是指待增加对象或者目标对象:切面通常包括对于基础的增加应用:配置是指AOP体系中提供的配置环境或者编织配置,通过该配置A ...

  8. 【Spring】Spring IOC原理及源码解析之scope=request、session

    一.容器 1. 容器 抛出一个议点:BeanFactory是IOC容器,而ApplicationContex则是Spring容器. 什么是容器?Collection和Container这两个单词都有存 ...

  9. RocketMQ原理及源码解析

    RocketMQ原理深入: 一.定义: RocketMQ是一款分布式.队列模型的消息中间件,有以下部分组成: 1.NameServer: 一个几乎无状态的节点,可集群部署,节点之间无任何信息同步 2. ...

随机推荐

  1. window下Jekyll建站过程

    > 前言 最近决定要写一个博客,先后注册了博客园和CSND的博客,但是他们的界面主题都不是很符合自己的要求,还没有足够个性化的发挥空间,遂决定自己建一个博客. 网上找了一下教程,感觉都不太详细, ...

  2. 项目经验:GIS<MapWinGIS>建模第三天

    记录下GIS工程进展

  3. Ubuntu14.04下如何安装Python爬虫框架Scrapy

    按照官方文档的说明,安装scrapy 需要以下程序或者库: (1).Python 2.7 (2).lxml. Most linux distributions ships PRepackaged ve ...

  4. C#复制粘贴

    用C#程序复制粘贴非常简单,这里为了实用,只介绍对文字的操作,其他情况类似: Clipboard.SetText(“我是需要复制到系统剪贴板的文字”); 执行以上代码后,即可ctrl+V进行粘贴.是不 ...

  5. SQLSERVER procedure 传入参数为DataTable类型 C#该怎么写

    以上为数据库中存储过程传入参数为table类型 table类型在数据库中存在为: 最后在C#实现方式为:

  6. double转换long的疑问

    在lua(5.1.4)下面测试的时候使用0x100000000的时候出现了问题,打印结果很明显,如下所示: Lua Copyright (C) - Lua.org, PUC-Rio > prin ...

  7. 图解:TCP协议中的三次握手和四次挥手

    建立TCP需要三次握手才能建立,而断开连接则需要四次握手.整个过程如下图所示: 先来看看如何建立连接的. 首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资 ...

  8. 第二周 day2 python学习笔记

    1. python中的三元运算: result=value1 if 条件 else value2 如果条件成立,result=value1 如果条件不成立,result=value2 2. pytho ...

  9. 2维FFT算法实现——基于GPU的基2快速二维傅里叶变换

    上篇讲述了一维FFT的GPU实现(FFT算法实现——基于GPU的基2快速傅里叶变换),后来我又由于需要做了一下二维FFT,大概思路如下. 首先看的肯定是公式: 如上面公式所描述的,2维FFT只需要拆分 ...

  10. 如何给Docker hub用户上传头像

    我第一次使用Docker hub时,觉得很奇怪,这个网站上面没有允许用户上传头像的地方. 后来经过研究才发现,需要用在Docker hub上注册用户的同一个邮箱到Gravatar这个网站上再注册一个账 ...