vue数据双向绑定原理
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数据双向绑定原理的更多相关文章
- 西安电话面试:谈谈Vue数据双向绑定原理,看看你的回答能打几分
最近我参加了一次来自西安的电话面试(第二轮,技术面),是大厂还是小作坊我在这里按下不表,先来说说这次电面给我留下印象较深的几道面试题,这次先来谈谈Vue的数据双向绑定原理. 情景再现: 当我手机铃声响 ...
- Vue数据双向绑定原理及简单实现
嘿,Goodgirl and GoodBoy,点进来了就看完点个赞再go. Vue这个框架就不简单介绍了,它最大的特性就是数据的双向绑定以及虚拟dom.核心就是用数据来驱动视图层的改变.先看一段代码. ...
- Vue数据双向绑定原理(vue2向vue3的过渡)
众所周知,Vue的两大重要概念: 数据驱动 组件系统 1 2 接下来我们浅析数据双向绑定的原理 一.vue2 1.认识defineProperty vue2中的双向绑定是基于definePropert ...
- vue的双向绑定原理及实现
前言 使用vue也好有一段时间了,虽然对其双向绑定原理也有了解个大概,但也没好好探究下其原理实现,所以这次特意花了几晚时间查阅资料和阅读相关源码,自己也实现一个简单版vue的双向绑定版本,先上个成果图 ...
- 【学习笔记】剖析MVVM框架,简单实现Vue数据双向绑定
前言: 学习前端也有半年多了,个人的学习欲望还比较强烈,很喜欢那种新知识在自己的演练下一点点实现的过程.最近一直在学vue框架,像网上大佬说的,入门容易深究难.不管是跟着开发文档学还是视频教程,按步骤 ...
- vue数据双向绑定的原理、虚拟dom的原理
vue数据双向绑定的原理https://www.cnblogs.com/libin-1/p/6893712.html 虚拟dom的原理https://blog.csdn.net/u010692018/ ...
- 对象的属性类型 和 VUE的数据双向绑定原理
如[[Configurable]] 被两对儿中括号 括起来的表示 不可直接访问他们 修改属性类型:使用Object.defineProperty() //IE9+ 和标准浏览器 支持 查看属性的 ...
- vue的双向绑定原理解析(vue项目重构二)
现在的前端框架 如果没有个数据的双向/单向绑定,都不好意思说是一个新的框架,至于为什么需要这个功能,从jq或者原生js开始做项目的前端工作者,应该是深有体会. 以下也是个人对vue的双向绑定原理的一些 ...
- vue的双向绑定原理浅析与简单实现
很久之前看过vue的一些原理,对其中的双向绑定原理也有一定程度上的了解,只是最近才在项目上使用vue,这才决定好好了解下vue的实现原理,因此这里对vue的双向绑定原理进行浅析,并做一个简单的实现. ...
随机推荐
- Oracle SQL Developer保持数据库连接的方法
一.概述 从navicat切到pl/sql developer,但是发现个bug,因为本地客户端pl/sql developer的字符集 和数据库服务器的字符集不一致,导致一个很奇葩的东西. 本来我有 ...
- spring boot 单元测试,如何使用profile
一.问题概述 spring boot项目.单元测试的时候,我发现,总是会使用application.properties的内容,而该文件里,一般是我的开发时候的配置. 比如上图中,dev是开发配置,p ...
- Android Usb Camera HAL框架
- C#中XML的读取
本文主要介绍在C#中有关XML的读取,写入操作. 1.XML的内容如下: <?xml version="1.0" encoding="utf-8" ?&g ...
- yii---where or该如何使用
今天调试YII项目的时候,遇到一个奇葩的事儿,在调试 where or 查询的时候:调试语句是这样: $str = static::find()->where(['or','username' ...
- poj-1989 The Cow Lineup
The Cow Lineup Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 5587 Accepted: 3311 Descri ...
- anaconda资源链接
清华源: https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ anaconda所有版本大全: http://www.bubuko.com/in ...
- stat命令的实现-mysate
任务详情 学习使用stat(1),并用C语言实现 提交学习stat(1)的截图 man -k,grep -r的使用 伪代码 产品代码mystate.c,提交码云链接 测试代码,mysate与stat( ...
- Pandas的append方法
相当于添加一行记录,这个方法也是比较管用的: # 测试pandas.append方法 def use_pd_append(): df = pd.DataFrame([[1, 2], [3, 4]], ...
- IOS--jenkins ,app,reengine
传统的对iOS逆向的工具要使用到下面很多: clutchotoolkeychain-dumpersqlitedumpdecryptedclass-dump-zTheos http://iosapp.m ...