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. Oracle SQL Developer保持数据库连接的方法

    一.概述 从navicat切到pl/sql developer,但是发现个bug,因为本地客户端pl/sql developer的字符集 和数据库服务器的字符集不一致,导致一个很奇葩的东西. 本来我有 ...

  2. spring boot 单元测试,如何使用profile

    一.问题概述 spring boot项目.单元测试的时候,我发现,总是会使用application.properties的内容,而该文件里,一般是我的开发时候的配置. 比如上图中,dev是开发配置,p ...

  3. Android Usb Camera HAL框架

  4. C#中XML的读取

    本文主要介绍在C#中有关XML的读取,写入操作. 1.XML的内容如下: <?xml version="1.0" encoding="utf-8" ?&g ...

  5. yii---where or该如何使用

    今天调试YII项目的时候,遇到一个奇葩的事儿,在调试 where or 查询的时候:调试语句是这样: $str = static::find()->where(['or','username' ...

  6. poj-1989 The Cow Lineup

    The Cow Lineup Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 5587 Accepted: 3311 Descri ...

  7. anaconda资源链接

    清华源: https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ anaconda所有版本大全: http://www.bubuko.com/in ...

  8. stat命令的实现-mysate

    任务详情 学习使用stat(1),并用C语言实现 提交学习stat(1)的截图 man -k,grep -r的使用 伪代码 产品代码mystate.c,提交码云链接 测试代码,mysate与stat( ...

  9. Pandas的append方法

    相当于添加一行记录,这个方法也是比较管用的: # 测试pandas.append方法 def use_pd_append(): df = pd.DataFrame([[1, 2], [3, 4]], ...

  10. IOS--jenkins ,app,reengine

    传统的对iOS逆向的工具要使用到下面很多: clutchotoolkeychain-dumpersqlitedumpdecryptedclass-dump-zTheos http://iosapp.m ...