浅谈Vue之双向绑定
VUE实现双向数据绑定的原理就是利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的。那么Object.defineProperty究竟是该如何使用的呢?先看个例子
<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head> <body>
<div id="app">
<h5 id="txtShow"></h5>
<input type="text" id="txt">
</div>
<script>
// mvvm 分为model(模型) view(视图) viewModel(视图模型)
// model 用来存储数据
// view 用来展示数据
// ViewModel 关联数据,和model实现双向绑定。 // 通过Object.defineProperty 定义一个属性
// 通过此方法为对象设置属性的时候 对象的属性值会包含一个get和set方法
// 当修改对象值得时候回触发相应的函数调用
// 参数一 需要定义属性的对象
// 参数二 属性名字
// 参数三 对象属性的修饰内容
// 在set方法中做一些处理,执行页面的刷新和回调
var model = {}; //创建一个新对象
var vm = '';
Object.defineProperty(model, 'txt', {
set: function (val) {
console.log('设置属性值');
console.log(val);
vm = val;
txtShow.innerHTML = this.txt;
},
get: function () {
console.log('获取属性值');
console.log(this);
return vm;
},
enumerable: true, //可枚举,默认false
configurable: true //该属性描述符能够被改变,同时该属性也能从对应的对象上被删除。默认false
}) var txtShow = document.getElementById('txtShow'),
txt = document.getElementById('txt'); txt.onkeyup = function () {
if (event.keyCode == 13) {
model.txt = txt.value;
}
}
</script>
</body> </html>
通过上面的代码我们可以看到,在控制台,无论是改变vm的值还是model.txt的值,所对应的的,对方的值也会相应的改变,由此,这里我们就实现了双向绑定。
对于Object.defineProperty() ,大家应该都见过,只是认知的程度有所不同。
根据MDN web docs 中解释说: Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
语法
Object.defineProperty(obj, prop, descriptor)
参数
obj- 要在其上定义属性的对象。
prop- 要定义或修改的属性的名称。
descriptor- 将被定义或修改的属性描述符。
返回值
被传递给函数的对象。
该方法允许精确添加或修改对象的属性。通过赋值操作添加的普通属性是可枚举的,能够在属性枚举期间呈现出来(for...in 或 Object.keys方法), 这些属性的值可以被改变,也可以被删除。这个方法允许修改默认的额外选项(或配置)。默认情况下,使用 Object.defineProperty() 添加的属性值是不可修改的。
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。存取描述符是由getter-setter函数对描述的属性。描述符必须是这两种形式之一;不能同时是两者。
数据描述符和存取描述符均具有以下可选键值:
configurable- 当且仅当该属性的 configurable 为 true 时,该属性
描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false。configurable特性表示对象的属性是否可以被删除,以及除value和writable特性外的其他特性是否可以被修改。 enumerable- 当且仅当该属性的
enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为 false。enumerable定义了对象的属性是否可以在for...in循环和Object.keys()中被枚举。 -
数据描述符同时具有以下可选键值:
value- 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为
undefined。 writable- 当且仅当该属性的
writable为true时,value才能被赋值运算符改变。默认为 false。
存取描述符同时具有以下可选键值:
| configurable | enumerable | value | writable | get | set | |
| 数据描述符 | YES | YES | YES | YES | NO | NO |
| 存取描述符 | YES | YES | NO | NO | YES | YES |
如果一个描述符不具有value,writable,get 和 set 任意一个关键字,那么它将被认为是一个数据描述符。如果一个描述符同时有(value或writable)和(get或set)关键字,将会产生一个异常。
记住,这些选项不一定是自身属性,如果是继承来的也要考虑。为了确认保留这些默认值,你可能要在这之前冻结 Object.prototype,明确指定所有的选项,或者通过 Object.create(null)将__proto__属性指向null。
在日常运用中,那你需要明白:
var o = {};
o.a = 1;
// 等同于 :
Object.defineProperty(o, "a", {
value : 1,
writable : true,
configurable : true,
enumerable : true
});
// 另一方面,
Object.defineProperty(o, "a", { value : 1 });
// 等同于 :
Object.defineProperty(o, "a", {
value : 1,
writable : false,
configurable : false,
enumerable : false
});
下面的例子展示了如何实现一个自存档对象。 当设置temperature 属性时,archive 数组会获取日志条目。
function Archiver() {
var temperature = null;
var archive = [];
Object.defineProperty(this, 'temperature', {
get: function() {
console.log('get!');
return temperature;
},
set: function(value) {
temperature = value;
archive.push({ val: temperature });
}
});
this.getArchive = function() { return archive; };
}
var arc = new Archiver();
arc.temperature; // 'get!'
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]
看到这个例子,你心中是不是有了些许想法?
后面还有很多知识点,有需要的可以去MDN进行更加深入的了解,谢谢!
浅谈Vue之双向绑定的更多相关文章
- 浅谈Vue.js
作为一名Vue.js的忠实用户,我想有必要写点文章来歌颂这一门美好的语言了,我给它的总体评价是“简单却不失优雅,小巧而不乏大匠”,下面将围绕这句话给大家介绍Vue.js,希望能够激发你对Vue.js的 ...
- 浅谈Vue响应式(数组变异方法)
很多初使用Vue的同学会发现,在改变数组的值的时候,值确实是改变了,但是视图却无动于衷,果然是因为数组太高冷了吗? 查看官方文档才发现,不是女神太高冷,而是你没用对方法. 看来想让女神自己动,关键得用 ...
- 【Vue】浅谈Vue(一):从模板语法数据绑定、指令到计算属性
写在前面 今年前端届比较有意思,从大漠穷秋发表文章比较angular和vue,继而致歉vue作者.社区,从谷歌辞去Angular Developer PM in China一职并且呼吁大家停止各种无谓 ...
- 西安电话面试:谈谈Vue数据双向绑定原理,看看你的回答能打几分
最近我参加了一次来自西安的电话面试(第二轮,技术面),是大厂还是小作坊我在这里按下不表,先来说说这次电面给我留下印象较深的几道面试题,这次先来谈谈Vue的数据双向绑定原理. 情景再现: 当我手机铃声响 ...
- Vue.js双向绑定的实现原理
Vue.js最核心的功能有两个,一是响应式的数据绑定系统,二是组件系统.本文仅探究几乎所有Vue的开篇介绍都会提到的hello world双向绑定是怎样实现的.先讲涉及的知识点,再参考源码,用尽可能少 ...
- Vue.js双向绑定的实现原理和模板引擎实现原理(##########################################)
Vue.js双向绑定的实现原理 解析 神奇的 Object.defineProperty 这个方法了不起啊..vue.js和avalon.js 都是通过它实现双向绑定的..而且Object.obser ...
- vue的双向绑定原理及实现
前言 使用vue也好有一段时间了,虽然对其双向绑定原理也有了解个大概,但也没好好探究下其原理实现,所以这次特意花了几晚时间查阅资料和阅读相关源码,自己也实现一个简单版vue的双向绑定版本,先上个成果图 ...
- 浅谈Vue不同场景下组件间的数据交流
浅谈Vue不同场景下组件间的数据“交流” Vue的官方文档可以说是很详细了.在我看来,它和react等其他框架文档一样,讲述的方式的更多的是“方法论”,而不是“场景论”,这也就导致了:我们在阅读完 ...
- Vue数据双向绑定原理及简单实现
嘿,Goodgirl and GoodBoy,点进来了就看完点个赞再go. Vue这个框架就不简单介绍了,它最大的特性就是数据的双向绑定以及虚拟dom.核心就是用数据来驱动视图层的改变.先看一段代码. ...
随机推荐
- 滴滴出行基于RocketMQ构建企业级消息队列服务的实践
小结: 1. https://mp.weixin.qq.com/s/v6NM3UgX-qTI7yO1QPCJrw 滴滴出行基于RocketMQ构建企业级消息队列服务的实践 原创: 江海挺 阿里巴巴中间 ...
- 学习ActiveMQ(六):JMS消息的确认与重发机制
当我们发送消息的时候,会出现发送失败的情况,此时我们需要用到activemq为我们提供了消息重发机制,进行消息的重新发送.那么我们怎么知道消息有没有发送失败呢?activemq还有消息确认机制,消费者 ...
- session and cookie
cookie cookie是由W3C组织提出,最早由Netscape社区发展的一种机制.目前Cookie已经成为标准,所有的主流浏览器如IE.Netscape.Firefox.Opera等都支持Coo ...
- 安装_oracle11G_客户端_服务端_链接_oracle
在开始之前呢,有一些注细节需要注意,oracle11G_客户端_和_服务端, 分为两种 一种是 开发者使用 一种是 BDA 自己使用(同时也需要根据自己 PC 的系统来做_win7_与 ...
- ambari卸载集群
#1.删除hdp.repo和hdp-util.repo cd /etc/yum.repos.d/ rm -rf hdp* rm -rf HDP* #rm -rf ambari* #2.删除安装包 #用 ...
- 【转】Spring Boot 构建应用——快速构建 Spring Boot 应用
Spring Boot 简化了 Spring 应用开发,不需要配置就能运行 Spring 应用,Spring Boot 的自动配置是通过 Spring 4.x 的条件注解 @Conditional 来 ...
- 【Linux】Mac Centos install VMware Tools
can't use yum: vi /etc/sysconfig/network-scripts/ifcfg-enp4s0 yum -y install lshw pciutils gdisk sys ...
- 干了这杯java之ThreadLocal
ThreadLocal Java篇 是什么 怎么用 源码 缺点 总结 是什么 ThreadLocal是一个关于创建线程局部变量的类,这个变量只能当前线程使用,其他线程不可用. ThreadLocal提 ...
- tensorflow(4)踩过的一些坑
版本问题 1.1 版本的一个BUG ValueError: Variable rnn/basic_lstm_cell/weights already exists, disallowed. 结合这个文 ...
- 接口自动化框架(java)--3.get,delete请求,Excel管理多种请求类型
这套框架的报告是自己封装的 每种请求类型放入不同的sheet中,就可以避免新建太多的excel去做数据驱动. XSSFSheet类提供了一个读取sheet的方法,getSheetAt(int),通过下 ...