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 相关文章推荐
function, new function, new Function之间的区别
Mar 08 Javascript
『jQuery』取指定url格式及分割函数应用
Apr 22 Javascript
js 立即调用的函数表达式如何写
Jan 12 Javascript
纯JS实现旋转图片3D展示效果
Apr 12 Javascript
JavaScript中String.match()方法的使用详解
Jun 06 Javascript
jQuery实现点击查看大图并以弹框的形式居中
Aug 08 Javascript
微信小程序 数组中的push与concat的区别
Jan 05 Javascript
解决LayUI表单获取不到data的问题
Aug 20 Javascript
vue2.x集成百度UEditor富文本编辑器的方法
Sep 21 Javascript
在vant中使用时间选择器和popup弹出层的操作
Nov 04 Javascript
解决vue init webpack 下载依赖卡住不动的问题
Nov 09 Javascript
小程序角标的添加及绑定购物车数量进行实时更新的实现代码
Dec 07 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调整服务器时间的方法
2015/04/03 PHP
PHP 数组遍历foreach语法结构及实例
2016/06/13 PHP
thinkPHP引入类的方法详解
2016/12/08 PHP
php + WebUploader实现图片批量上传功能
2019/05/06 PHP
js 图片等比例缩放代码
2010/05/13 Javascript
基于jquery的has()方法以及与find()方法以及filter()方法的区别详解
2013/04/26 Javascript
JS实现兼容各种浏览器的高级拖动方法完整实例【测试可用】
2016/06/21 Javascript
用自定义图片代替原生checkbox实现全选,删除以及提交的方法
2016/10/18 Javascript
Javascript vue.js表格分页,ajax异步加载数据
2016/10/24 Javascript
微信小程序 数组中的push与concat的区别
2017/01/05 Javascript
es6的数字处理的方法(5个)
2017/03/16 Javascript
详解angularjs获取元素以及angular.element()用法
2017/07/25 Javascript
详解a++和++a的区别
2017/08/30 Javascript
React Native中的RefreshContorl下拉刷新使用
2017/10/09 Javascript
vue综合组件间的通信详解
2017/11/06 Javascript
jQuery动态添加元素无法触发绑定事件的解决方法分析
2018/01/02 jQuery
基于Express框架使用POST传递Form数据
2019/08/10 Javascript
Vue环境搭建+VSCode+Win10的详细教程
2020/08/19 Javascript
[44:43]完美世界DOTA2联赛决赛日 FTD vs GXR 第一场 11.08
2020/11/11 DOTA
零基础写python爬虫之使用Scrapy框架编写爬虫
2014/11/07 Python
python实现多进程代码示例
2018/10/31 Python
解决pyinstaller打包exe文件出现命令窗口一闪而过的问题
2018/10/31 Python
Centos部署django服务nginx+uwsgi的方法
2019/01/02 Python
python requests证书问题解决
2019/09/05 Python
Node.js 和 Python之间该选择哪个?
2020/08/05 Python
Cole Haan官方网站:美国时尚潮流品牌
2017/12/06 全球购物
毕业生就业意向书
2014/04/01 职场文书
篮球社团活动总结
2014/06/27 职场文书
民政局副局长民主生活会个人整改措施
2014/10/04 职场文书
上班迟到检讨书300字
2014/10/18 职场文书
2014年度安全工作总结
2014/12/04 职场文书
2016春季幼儿园小班开学寄语
2015/12/03 职场文书
2016年庆祝六一儿童节活动总结
2016/04/06 职场文书
Win11 引入 Windows 365 云操作系统,适应疫情期间混合办公模式:启动时直接登录、模
2022/04/06 数码科技
PostgreSQL数据库创建并使用视图以及子查询
2022/04/11 PostgreSQL
Vue 打包后相对路径的引用问题
2022/06/05 Vue.js