Vue实现双向数据绑定


Posted in Javascript onMay 03, 2017

Vue实现双向数据绑定的方式,具体内容如下

Vue是如何实现双向数据绑定的呢?答案是前端数据劫持。其通过Object.defineProperty()方法,这个方法可以设置getter和setter函数,在setter函数中,就可以监听到数据的变化,从而更新绑定的元素的值。

实现对象属性变化绑定到UI

大概的思路是:

1. 确定绑定的数据,使用Object.defineProperty()对其数据变化进行监听(对应defineGetAndSet)
2. 一旦数据发生改动,会触发setter函数。因此在setter函数内要调用回调函数触发绑定元素的更新。
3. 绑定元素的更新就是遍历所有的绑定元素,通过绑定属性的值确定函数的调用,并传入修改后的值。(对应scan)

实现UI变化绑定到对象属性

这个就比较简单了,因为UI的改变会触发一些事件,比如keyup。通过监听事件来实现数据的改变。而上面说了,数据的改变又会导致绑定其值的元素的UI改变。

实现

var data = {
 value: 'hello world!'
}
var bindValue;
//确定绑定的元素
var bindelems = [document.getElementById('p'), document.getElementById('input')];
//修改绑定元素的值的方法
var command = {
 text: function(str) {
 this.innerHTML = str;
 },
 value: function(str) {
 this.value = str;
 }
};
//遍历绑定元素修改其值
var scan = function() {
 console.log('in scan');
 for(var i = 0; i < bindelems.length; i++) {
 var elem = bindelems[i];
 console.log('elem',elem);
 for(var j = 0; j < elem.attributes.length; j++) {
 var attr = elem.attributes[j];
 if(attr.nodeName.indexOf('q-')>=0) {
 command[attr.nodeName.slice(2)].call(elem, data[attr.nodeValue]);
 }
 }
 }
}
//设置劫持
var defineGetAndSet = function(obj, propname) {
 Object.defineProperty(obj, propname, {
 get: function() {
 return bindValue;
 },
 set: function(value){
 bindValue = value;
 scan();
 },
 enumerable: true,
 configurable: true
 })
} 
//一开始先初始化,使所有绑定的元素值为初始值
scan();
//设置需要被劫持的元素
defineGetAndSet(data, 'value');
//监听UI变化
bindelems[1].addEventListener('keyup', function(e) {
 data.value = e.target.value;
});
setTimeout(function() {
 data.value = 'change';
}, 1000);

参考:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS中==与===操作符的比较
Mar 21 Javascript
javascript的onchange事件与jQuery的change()方法比较
Sep 28 Javascript
javascript 二进制运算技巧解析
Nov 27 Javascript
JS实现两个大数(整数)相乘
Apr 28 Javascript
BOOTSTRAP时间控件显示在模态框下面的bug修复
Feb 05 Javascript
jQuery.ajax 跨域请求webapi设置headers的解决方案
Aug 08 Javascript
AngularJS学习笔记(三)数据双向绑定的简单实例
Nov 08 Javascript
一篇文章搞定JavaScript类型转换(面试常见)
Jan 21 Javascript
什么是Vue.js框架 为什么选择它?
Oct 17 Javascript
微信小程序之swiper滑动面板用法示例
Dec 04 Javascript
uni-app微信小程序登录并使用vuex存储登录状态的思路详解
Nov 04 Javascript
在vue中使用echarts(折线图的demo,markline用法)
Jul 20 Javascript
Angular 4.x 路由快速入门学习
May 03 #Javascript
javaScript 逻辑运算符使用技巧整理
May 03 #Javascript
浅谈Node.js轻量级Web框架Express4.x使用指南
May 03 #Javascript
vue的Virtual Dom实现snabbdom解密
May 03 #Javascript
JavaScript中undefined和null的区别
May 03 #Javascript
Node.js对MongoDB数据库实现模糊查询的方法
May 03 #Javascript
xmlplus组件设计系列之文本框(TextBox)(3)
May 03 #Javascript
You might like
让你的PHP同时支持GIF、png、JPEG
2006/10/09 PHP
Yii框架日志记录Logging操作示例
2018/07/12 PHP
PHP explode()函数用法讲解
2019/02/15 PHP
PHP接入微信H5支付的方法示例
2019/10/28 PHP
Javascript面向对象设计一 工厂模式
2011/12/20 Javascript
javascript实现的弹出层背景置灰-模拟(easyui dialog)
2013/12/27 Javascript
JavaScript实现Java中StringBuffer的方法
2015/02/09 Javascript
详谈javascript中DOM的基本属性
2015/02/26 Javascript
jQuery支持添加事件的日历特效代码分享(3种样式)
2015/08/24 Javascript
浅析jQuery中使用$所引发的问题
2016/05/29 Javascript
Reactjs实现通用分页组件的实例代码
2017/01/19 Javascript
jQuery.cookie.js使用方法及相关参数解释
2017/03/06 Javascript
JavaScript mixin实现多继承的方法详解
2017/03/30 Javascript
详解vue组件通信的三种方式
2017/06/30 Javascript
基于百度地图api清除指定覆盖物(Overlay)的方法
2018/01/26 Javascript
关于单文件组件.vue的使用
2018/09/20 Javascript
微信小程序实现日期格式化和倒计时
2020/11/01 Javascript
在Python的Flask框架中实现全文搜索功能
2015/04/20 Python
Python的Tornado框架实现图片上传及图片大小修改功能
2016/06/30 Python
网站渗透常用Python小脚本查询同ip网站
2017/05/08 Python
python实现控制COM口的示例
2019/07/03 Python
python实现的发邮件功能示例
2019/09/11 Python
使用sklearn的cross_val_score进行交叉验证实例
2020/02/28 Python
Python unittest单元测试框架实现参数化
2020/04/29 Python
Python 列表中的修改、添加和删除元素的实现
2020/06/11 Python
Claire’s法国:时尚配饰、美容、珠宝、头发
2021/01/16 全球购物
自荐信范文
2013/12/10 职场文书
党的群众路线教育实践活动教师自我剖析材料
2014/10/09 职场文书
2014年底工作总结
2014/12/15 职场文书
关于拾金不昧的感谢信
2015/01/21 职场文书
2015年材料员工作总结
2015/04/30 职场文书
社区党建工作总结2015
2015/05/13 职场文书
催款函范文
2015/06/24 职场文书
捐款仪式主持词
2015/07/04 职场文书
教师年度考核自我评鉴
2015/08/11 职场文书
logback 实现给变量指定默认值
2021/08/30 Java/Android