vue的数据双向绑定的小例子:

。html

<!DOCTYPE html>
<html>
<head>
<meta charset=utf->
<title>vue数据双向绑定原理</title>
</head>
<body>
<h1 id="name"><<<<name>>>>>></h1>
</body>
<script src="testvuejs/observer.js"></script>
<script src="testvuejs/watcher.js"></script>
<script src="testvuejs/index.js"></script>
<script type="text/javascript">
var ele = document.querySelector('#name');
var selfVue = new SelfVue({
name: 'hello world'
}, ele, 'name');
window.setTimeout(function () {
console.log('name值改变了');
selfVue.name = 'canfoo';
}, );
</script>
</html>

index.js

function SelfVue (data, el, exp) {
var self = this;
this.data = data; //把data里的key直接绑定到this对象上
Object.keys(data).forEach(function(key) {
self.proxyKeys(key);
}); //对data的每一层级的属性进行监听,如果变化执行notify
observe(data); // 初始化模板数据的值
el.innerHTML = this.data[exp]; new Watcher(this, exp, function (value) {
el.innerHTML = value;
});
return this;
} SelfVue.prototype = {
proxyKeys: function (key) {
Object.defineProperty(this, key, {
enumerable: false,
configurable: true,
get: ()=> {
return this.data[key];
},
set: (newVal)=> {
this.data[key] = newVal;
}
});
}
}

observer.js

function Observer(data) {
this.data = data;
this.walk(data);
}
Observer.prototype = {
walk: function(data) {
var self = this;
Object.keys(data).forEach(function(key) {
self.defineReactive(data, key, data[key]);
});
},
defineReactive: function(data, key, val) {
var dep = new Dep();
//对二级三级子属性...进行监听尽
observe(val);
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get: function() {
if (Dep.target) {
dep.addSub(Dep.target);
}
return val;
},
set: function(newVal) {
if (newVal === val) {
return;
}
val = newVal;
dep.notify();
}
});
}
}; function observe(value, vm) {
if (!value || typeof value !== 'object') {
return;
}
return new Observer(value);
}; function Dep () {
this.subs = [];
}
Dep.prototype = {
addSub: function(sub) {
this.subs.push(sub);
},
notify: function() {
this.subs.forEach(function(sub) {
sub.update();
});
}
};
Dep.target = null;

watcher.js

function Watcher(vm, exp, cb) {
this.cb = cb;
this.vm = vm;
this.exp = exp;
//当new一个对象的时候,立即执行get方法,Dep的target为Watcher自己
this.value = this.get(); // 将自己添加到订阅器的操作
} Watcher.prototype = {
update: function() {
this.run();
},
run: function() {
var value = this.vm.data[this.exp];
var oldVal = this.value;
if (value !== oldVal) {
this.value = value;
this.cb.call(this.vm, value);
}
},
get: function() {
Dep.target = this; // 缓存自己
var value = this.vm.data[this.exp] // this.vm.data[this.exp]:强制执行监听器里的get函数,使自己(Watcher {cb: ƒ, vm: SelfVue, exp: "name"})被添加上
Dep.target = null; // 释放自己
return value;
}
};

原理:当new vue后,将data属性直接给vm添加上,将属性的每一级进行set get 当set新值时通知notify函数。执行 new watcher ,强制执行data的get 使watch被添加上。

当data set新值时,触发notify函数,使所有watcher都执行update,watcher的update时,本地的value是旧值,取新值,回调函数更新view。

vue数据双向绑定原理的更多相关文章

  1. 西安电话面试:谈谈Vue数据双向绑定原理,看看你的回答能打几分

    最近我参加了一次来自西安的电话面试(第二轮,技术面),是大厂还是小作坊我在这里按下不表,先来说说这次电面给我留下印象较深的几道面试题,这次先来谈谈Vue的数据双向绑定原理. 情景再现: 当我手机铃声响 ...

  2. Vue数据双向绑定原理及简单实现

    嘿,Goodgirl and GoodBoy,点进来了就看完点个赞再go. Vue这个框架就不简单介绍了,它最大的特性就是数据的双向绑定以及虚拟dom.核心就是用数据来驱动视图层的改变.先看一段代码. ...

  3. Vue数据双向绑定原理(vue2向vue3的过渡)

    众所周知,Vue的两大重要概念: 数据驱动 组件系统 1 2 接下来我们浅析数据双向绑定的原理 一.vue2 1.认识defineProperty vue2中的双向绑定是基于definePropert ...

  4. vue的双向绑定原理及实现

    前言 使用vue也好有一段时间了,虽然对其双向绑定原理也有了解个大概,但也没好好探究下其原理实现,所以这次特意花了几晚时间查阅资料和阅读相关源码,自己也实现一个简单版vue的双向绑定版本,先上个成果图 ...

  5. 【学习笔记】剖析MVVM框架,简单实现Vue数据双向绑定

    前言: 学习前端也有半年多了,个人的学习欲望还比较强烈,很喜欢那种新知识在自己的演练下一点点实现的过程.最近一直在学vue框架,像网上大佬说的,入门容易深究难.不管是跟着开发文档学还是视频教程,按步骤 ...

  6. vue数据双向绑定的原理、虚拟dom的原理

    vue数据双向绑定的原理https://www.cnblogs.com/libin-1/p/6893712.html 虚拟dom的原理https://blog.csdn.net/u010692018/ ...

  7. 对象的属性类型 和 VUE的数据双向绑定原理

    如[[Configurable]] 被两对儿中括号 括起来的表示 不可直接访问他们 修改属性类型:使用Object.defineProperty()  //IE9+  和标准浏览器  支持 查看属性的 ...

  8. vue的双向绑定原理解析(vue项目重构二)

    现在的前端框架 如果没有个数据的双向/单向绑定,都不好意思说是一个新的框架,至于为什么需要这个功能,从jq或者原生js开始做项目的前端工作者,应该是深有体会. 以下也是个人对vue的双向绑定原理的一些 ...

  9. vue的双向绑定原理浅析与简单实现

    很久之前看过vue的一些原理,对其中的双向绑定原理也有一定程度上的了解,只是最近才在项目上使用vue,这才决定好好了解下vue的实现原理,因此这里对vue的双向绑定原理进行浅析,并做一个简单的实现. ...

随机推荐

  1. nginx(一)----ubuntu14.04下安装nginx

    /** * lihaibo * 文章内容都是根据自己工作情况实践得出. *如有错误,请指正 *转载请注明出处 */ 此文章中用到的软件下载地址: 链接: http://pan.baidu.com/s/ ...

  2. Egret容器的鼠标默认事件

    容器的鼠标默认事件   touchEnabled touchChildren touchThrough DisplayObject false \ \ DisplayObjectContainer f ...

  3. Java虚拟机七 虚拟机监控

    jstack 用于导出Java应用程序的线程堆栈:jstack [-l] <pid> -l 选项用于打印锁的附加信息 jstack -l 2348 > /data/deadlock. ...

  4. Mac下更新SVN

    Mac下自带的SVN版本还是1.6的,而最新的Versions已经更新到支持1.7版本了,在Windows下面使用1.7版本久了所以也想更新下Mac版本. OK,废话不多说,简单描述操作步骤: 去Ap ...

  5. pandas 中的DataFrame.where()使用

    pandas.DataFrame.where DataFrame.where(cond, other=nan, inplace=False, axis=None, level=None, try_ca ...

  6. baidu.com直接访问网站,不跳转www.baidu.com

    平常最多的需求是将baidu.com指向全域名www.badu.com,但是往往需求是各种各样,这两天就遇到一个反向需求.将baidu.com直接访问网站,而不做跳转. 最近两天在给域名证书续费,但是 ...

  7. C语言清屏函数

    Devc++ 与VC中的清屏函数 #include<stdio.h> #include<stdlib.h>//清屏函数的头文 int main() { int i; for(i ...

  8. opencv学习笔记之cvSobel 函数解析

    首先,我们来开一下计算机是如何检测边缘的.以灰度图像为例,它的理论基础是这样的,如果出现一个边缘,那么图像的灰度就会有一定的变化,为了方便假设由黑渐变为白代表一个边界,那么对其灰度分析,在边缘的灰度函 ...

  9. POJ 1556 - The Doors - [平面几何+建图spfa最短路]

    题目链接:http://poj.org/problem?id=1556 Time Limit: 1000MS Memory Limit: 10000K Description You are to f ...

  10. Win_Server_2008 安装 Oracle_11g EM时上载EM资料失败

    此问题本人也遇到过.在网上找到了解决方案.下部分引用IT PUB. 安装oracle11g 64位.创建数据库到快结束的时候,报告说EM无法创建.emca_2010_06_13_11_05_36.lo ...