js实现数据双向绑定
接上一篇文章《js实现数据单向绑定》
上篇文章中用原生js实现了数据的单向绑定。本篇文章继续介绍如何用js实现数据的双向绑定。绑定的方式模仿vue中的v-model
指令。
创建标签
<div id="div1"> <input type="text" v-model="name"> <br> 姓名:{{name}} </div>
创建一个输入框,使用v-model属性绑定变量name,注意这里只是模仿vue绑定的形式,代码中并没有引入任何vue依赖。完全靠原生js实现。
单向绑定
let el = document.getElementById('app'); let template = el.innerHTML; let _data = { name: '_BuzzLy' }; let data = new Proxy(_data, { set(obj, name, value) { obj[name] = value; render(); } }); render(); function render() { el.innerHTML = template.replace(/\{\{\w+\}\}/g, str => { str = str.substring(2, str.length - 2); return _data[str]; }); }
到这我们又实现了一遍单向绑定,想要实现数据的双向绑定其实很简单,只需稍微修改我们的render函数。
双向绑定
function render() { el.innerHTML = template.replace(/\{\{\w+\}\}/g, str => { str = str.substring(2, str.length - 2); return _data[str]; }); // 找到所有input标签 Array.from(el.getElementsByTagName('input')) // 过滤得到其中带有v-model属性的标签 .filter(ele => ele.getAttribute('v-model')) // 遍历这些input标签 .forEach(input => { // 获取到v-model中绑定的key,从数据中找到key对应的value赋给input // 这一步就相当于数据=>视图的绑定 let name = input.getAttribute('v-model'); input.value = _data[name]; // 为input绑定输入事件 input.oninput = function () { // 当input修改时,将修改后的值赋给暴露在外的data对象 // 这一步就实现了视图=>数据的绑定 data[name] = this.value; }; }); }
修改后的render函数通过过滤、遍历得到每一个拥有v-model属性的input标签,然后将数据绑定到视图上,并且视图修改也会触发数据的更新,这样就实现了数据的双向绑定。
看似复杂的绑定机制其实就是通过我们熟悉的js一些基础的操作来实现的。
完整代码
<!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title></title> </head> <body> <div id="div1"> <input type="text" v-model="name"> <br> 姓名:{{name}} </div> </body> <script> let el = document.getElementById('div1'); let template = el.innerHTML; let _data = { name: '_BuzzLy' }; let data = new Proxy(_data, { set(obj, name, value) { obj[name] = value; render(); } }); render(); function render() { el.innerHTML = template.replace(/\{\{\w+\}\}/g, str => { str = str.substring(2, str.length - 2); return _data[str]; }); Array.from(el.getElementsByTagName('input')) .filter(ele => ele.getAttribute('v-model')) .forEach(input => { let name = input.getAttribute('v-model'); input.value = _data[name]; input.oninput = function () { data[name] = this.value; }; }); } </script> </html>
原文地址:https://segmentfault.com/a/1190000021242927
相关推荐
-
剑指offer·JS版 | 从尾到头打印链表 javascript/jquery
2020-5-26
-
Flutter Web入门 javascript/jquery
2020-6-27
-
90行JS代码构建属于你的React javascript/jquery
2020-5-20
-
如何写出一个惊艳面试官的深拷贝? javascript/jquery
2019-9-7
-
JavaScript中对象的浅复制和深复制 javascript/jquery
2019-4-4
-
唠一唠call、apply和bind以及手动实现(拒绝晦涩难懂) javascript/jquery
2019-11-1
-
前端工程师必懂面试题之浏览器输入URL之后发生了什么 javascript/jquery
2020-5-26
-
重拾JS——防抖与节流 javascript/jquery
2020-5-20
-
Node要领 javascript/jquery
2020-5-23
-
JS里循环截取(slice)数组中固定长度,获取新数组。 javascript/jquery
2020-5-23