什么是双向绑定?

 双向,逻辑层<->视图层

绑定,当任一层发生变化时,要在另一层得到体现

即,当视图层有用户输入时,输入数据会自动传递给逻辑层。而当逻辑层有数据变化时,视图层会自动展示这些变化

image.png

 

如何做?

 首先,我们需要关注的点,是变化。围绕变化本身,我们进一步需要知道是谁、在什么时候、发生了什么事,最后产生了什么内容。

image.png

 监听,我们需要监听相关元素,比如视图层,想要获悉文本框内容变化,就监听文本框input事件,以此类推。

 

 

 

 同步更新,当监听到变化时,我们要把变化同步更新到另一个层。包含对象赋值,表单元素渲染等。

示例(一)

监听页面与js对象,并在变化发生时通知对方做出相应变化。

image.png

 监听页面元素,遍历所有相关元素,并监听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方法返回值问题。