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 相关文章推荐
跟随鼠标旋转的文字
Nov 30 Javascript
让FireFox支持innerText的实现代码
Dec 01 Javascript
javascript之通用简单的table选项卡实现(二)
May 09 Javascript
Jquery下:nth-child(an+b)的使用注意
May 28 Javascript
Extjs Label的 fieldLabel和html属性值对齐的方法
Jun 15 Javascript
JavaScript设计模式之建造者模式介绍
Dec 28 Javascript
JavaScript设计模式之单件模式介绍
Dec 28 Javascript
JavaScript隐式类型转换
Mar 15 Javascript
JS实用的带停顿的逐行文本循环滚动效果实例
Nov 23 Javascript
JS中Object对象的原型概念基础
Jan 29 Javascript
使用vue-router设置每个页面的title方法
Feb 11 Javascript
element-ui 的el-button组件中添加自定义颜色和图标的实现方法
Oct 26 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调用方法mssql_fetch_row、mssql_fetch_array、mssql_fetch_assoc和mssql_fetch_objcect读取数据的区别
2012/08/08 PHP
使用swoole 定时器变更超时未支付订单状态的解决方案
2019/07/24 PHP
php连接sftp的作用以及实例代码
2019/09/23 PHP
超级强大的表单验证
2006/06/26 Javascript
ext监听事件方法[初级篇]
2008/04/27 Javascript
jQuery(1.3.2) 7行代码搞定跟随屏幕滚动的层
2009/05/21 Javascript
Javascript 日期处理之时区问题
2009/10/08 Javascript
jQuery EasyUI API 中文文档 - Spinner微调器使用
2011/10/21 Javascript
使用js实现按钮控制文本框加1减1应用于小时+分钟
2013/12/09 Javascript
jquery动态加载select下拉框示例代码
2013/12/10 Javascript
jQuery插件分享之分页插件jqPagination
2014/06/06 Javascript
angularJS 入门基础
2015/02/09 Javascript
jQuery焦点图轮播特效代码分享(3款)
2015/09/05 Javascript
JQuery+EasyUI轻松实现步骤条效果
2016/02/22 Javascript
jQuery ajaxSubmit 实现ajax提交表单局部刷新
2016/07/04 Javascript
Bootstrap中表单控件状态(验证状态)
2016/08/04 Javascript
浅谈EasyUI常用控件的禁用方法
2016/11/09 Javascript
js倒计时小实例(多次定时)
2016/12/08 Javascript
swiper 解决动态加载数据滑动失效的问题
2018/02/26 Javascript
Vuex 快速入门(简单易懂)
2018/09/20 Javascript
[50:34]VGJ.T vs Fnatic 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
python实现ftp客户端示例分享
2014/02/17 Python
python在linux中输出带颜色的文字的方法
2014/06/19 Python
Python引用(import)文件夹下的py文件的方法
2014/08/26 Python
基于python的字节编译详解
2017/09/20 Python
Django框架实现逆向解析url的方法
2018/07/04 Python
Python实现朴素贝叶斯分类器的方法详解
2018/07/04 Python
Python模块的加载讲解
2019/01/15 Python
python3安装OCR识别库tesserocr过程图解
2020/04/02 Python
Python collections.defaultdict模块用法详解
2020/06/18 Python
Python reversed反转序列并生成可迭代对象
2020/10/22 Python
戴尔荷兰官方网站:Dell荷兰
2020/10/04 全球购物
《那片绿绿的爬山虎》教学反思
2014/02/27 职场文书
好书伴我成长演讲稿
2014/05/14 职场文书
公务员上班玩游戏检讨书
2014/09/17 职场文书
2015年女生节活动总结
2015/02/27 职场文书