什么是双向绑定?
双向,逻辑层<->视图层
绑定,当任一层发生变化时,要在另一层得到体现
即,当视图层有用户输入时,输入数据会自动传递给逻辑层。而当逻辑层有数据变化时,视图层会自动展示这些变化
如何做?
首先,我们需要关注的点,是变化。围绕变化本身,我们进一步需要知道是谁、在什么时候、发生了什么事,最后产生了什么内容。
监听,我们需要监听相关元素,比如视图层,想要获悉文本框内容变化,就监听文本框input事件,以此类推。
同步更新,当监听到变化时,我们要把变化同步更新到另一个层。包含对象赋值,表单元素渲染等。
示例(一)
监听页面与js对象,并在变化发生时通知对方做出相应变化。
监听页面元素,遍历所有相关元素,并监听input事件,当监听到时则将当前文本框内容赋值给对应的变量。
//选择根元素
let root = document.querySelector(_this.el); const nodes = root.children; //遍历所有节点 Object.values(nodes).forEach(nodeChild => { //选择包含v-model属性的节点 if (nodeChild.hasAttribute('v-model')) { //监听input事件 nodeChild.addEventListener('input', function (res) { let attrVal = nodeChild.getAttribute('v-model'); _this.data[attrVal] = nodeChild.value; }); } });
备注:
当前实现仅能遍历一级节点,并且只能监听v-model属性。
监听js对象,遍历js对象,监听对象的每个属性,但属性发生改变时将对象值同步到相应的文本框。
for(let i in _this.data) { let temp = null; //监听对象变化 Object.defineProperty(_this.data, i, { get:function() { return temp; }, set: function(value) { temp = value; //遍历页面元素 _this.forEachEl(function(nodeChild){ let attrVal = nodeChild.getAttribute('v-model'); if(attrVal == i) nodeChild.value = value; }); } }); }
备注:
1、要考虑视图层元素的嵌套,确保可以遍历到所有要遍历的元素以及不需要遍历的元素。
2、要熟悉Object.defineProperty的用法,特别注意其中的get方法返回值问题。