前言 上次写了一个Object.defineProperty() 不详解,文末说要写用它来写个双向绑定。说话算话,说来就来
前文链接 Object.defineProperty() 不详解
先看最后效果
model演示.gif
什么是双向绑定?
1.当一个对象(或变量)的属性改变,那么调用这个属性的地方显示也应该改变,模型到视图(model => view)
2.当调用属性的这个地方改变了这个属性(通常是一个表单元素),那么这个对象(或变量)的属性也会改为最新的值 ,即视图到模型(view => model)
我们怎么知道对象的属性变了?
上文说到,Object.defineProperty 设置对象属性的描述字段里面有两个属性 set (设置属性时被调用)和get(获取属性时被调用)
,只说不练,你再讲什么?眼见为实好吗?OK ,上代码
var user = {}; var defaultName = "狂奔的蜗牛"; Object.defineProperty(user,"name",{ get:function(){ console.log("你是不是来获取值啦"); return defaultName; }, set:function(value){ console.log("你是不是来设置值啦"); defaultName = value; } }) console.log(user.name); user.name = "狂奔的萝卜"; console.log(user.name);
get和set存取时被调用
如上图所示 每当我获取user.name属性时,get方法被调用,get 方法对应的函数被执行,输出 你是不是来获取值啦;每当我设置user.name属性时,set方法对应的函数被执行,输出 你是不是来设置值啦 ; 是的,我们监控到了代码对user.name属性的存取。
说明 假设id="model" 的元素的 value 是user.name的值,既然我们可以在改变属性的执行日志输出(console.log("你是不是来设置值啦");),那么,我们在设置值的时候给id="model" 的元素设置下新值,不就实现了从模型到视图?!!,说干就干
模型到视图(model => view)的同步
说明 假设id="model" 的元素的 value 是user.name的值,既然我们可以在改变属性的执行日志输出(console.log("你是不是来设置值啦");),那么,我们在设置值的时候给id="model" 的元素设置下新值,不就实现了从模型到视图?!!,说干就干
<body> 手写一个简单双向绑定<br/> <input type="text" id="model"><br/> <div id="modelText"></div> </body> <script> var user = {}; var defaultName = "狂奔的蜗牛"; document.querySelector("#model").value = defaultName; document.querySelector("#modelText").textContent = defaultName; //定义属性 监控改变 Object.defineProperty(user,"name",{ get:function(){ console.log("你是不是来获取值啦"); return defaultName; }, set:function(newValue){ console.log("设置新值"); defaultName = newValue; console.log("实现 模型 => 视图"); document.querySelector("#model").value = newValue; document.querySelector("#modelText").textContent = newValue; } }) console.log("2s 后改变值"); setTimeout(() => { //改变值 user.name = "狂奔的萝卜"; }, 2000); </script>
模型到视图(model => view)的同步
视图到模型(view => model)的同步
问: 我们能捕捉到view对值更改吗?
答:可以!! id="model" 的input元素的 value 是user.name的值,填充在这个文本框里面,文本框有个“ keyup” 事件,当我们在文本框中输入文字的时候,文本框的值会跟着改变,并且会连续触发keyup事件,那么我们只需要监听这个事件,是不是就可以捕捉到view对值的更改了??既然文本框的值会跟着改变,我们获取最新的值再把新值更新到user.name属性,不就实现了视图到模型(view => model)的同步?没代码说个啥
<body> 手写一个简单双向绑定<br/> <input type="text" id="model"><br/> <div id="modelText"></div> </body> <script> var user = {}; var defaultName = "狂奔的蜗牛"; var model = document.querySelector("#model"); var modelText = document.querySelector("#modelText"); model.value = defaultName; modelText.textContent = defaultName; //定义属性 监控改变 Object.defineProperty(user,"name",{ get:function(){ console.log("你是不是来获取值啦"); return defaultName; }, set:function(newValue){ console.log("设置新值"); defaultName = newValue; model.value = newValue; modelText.textContent = newValue; } }) model.addEventListener("keyup", function () { user.name = this.value; console.log("实现 视图 => 模型"); }, false) </script>
view2model.gif
【最终源码】
在上述代码的基础上,加入了 用户输入中文的判断(用户输入中文时,频繁触发 keyup事件,但实际上输入并没有结束。)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>双向绑定</title> </head> <body> 手写一个简单双向绑定<br/> <input type="text" id="model"><br/> <div id="modelText"></div> </body> <script> var model = document.querySelector("#model"); var modelText = document.querySelector("#modelText"); var defaultName = "defaultName"; var userInfo = {} model.value = defaultName; Object.defineProperty(userInfo, "name", { get: function () { return defaultName; }, set: function (value) { defaultName = value; model.value = value; console.log("-----value"); console.log(value); modelText.textContent = value; } }) userInfo.name = "new value"; var isEnd = true; model.addEventListener("keyup", function () { if (isEnd) { userInfo.name = this.value; } }, false) //加入监听中文输入事件 model.addEventListener("compositionstart", function () { console.log("开始输入中文"); isEnd = false; }) model.addEventListener("compositionend", function () { isEnd = true; console.log("结束输入中文"); }) </script> </html>
【完结】
Object.defineProperty 可以做很多好玩儿的,自己慢慢探索哈~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
更新日志
- 炉石传说抢先乱斗卡组有什么 深暗领域抢先体验乱斗卡组推荐
- 荣耀手机腕上最佳搭档 荣耀手表5首销开启
- 雷克沙ARES 6000 C28战神之翼 AMD 9800X3D超强搭档
- 咪咕快游感恩同游,超值回馈尽在咪咕咪粉节!
- 陈崎凡《CHEN》[FLAC/分轨][326.32MB]
- 群星《我们的歌第六季 第2期》[320K/MP3][74.05MB]
- 群星《我们的歌第六季 第2期》[FLAC/分轨][385.16MB]
- 童丽《每一个晚上》[低速原抓WAV+CUE]
- 乌兰齐齐格《呼伦牧歌》[原抓WAV+CUE]
- 黄乙玲1988-无稳定的爱心肝乱糟糟[日本东芝1M版][WAV+CUE]
- 群星《我们的歌第六季 第3期》[320K/MP3][70.68MB]
- 群星《我们的歌第六季 第3期》[FLAC/分轨][369.48MB]
- 群星《燃!沙排少女 影视原声带》[320K/MP3][175.61MB]
- 乱斗海盗瞎6胜卡组推荐一览 深暗领域乱斗海盗瞎卡组分享
- 炉石传说乱斗6胜卡组分享一览 深暗领域乱斗6胜卡组代码推荐