JavaScript实现一个简单的双向绑定

一、基本实现

<body>
    <input type="text" id='input'>
    <span id="show"></span>
</body>
<script>
    var obj = {} 

    Object.defineProperty(obj, 'txt', {
        get: function(){
            return obj
        },
        set: function(newValue){           
            document.getElementById('input').value = newValue
            document.getElementById('show').innerHTML = newValue
        }
    })
    
    document.getElementById('input').addEventListener('keyup', function(e){
       obj.txt = e.target.value
    })
</script>

解析其原理:
JavaScript实现一个简单的双向绑定_第1张图片

当通过input进行输入时,span的文本值会相应更新;当通过控制台改变obj.txt的值时,input输入框内的值也会相应改变,从而实现了view=>model,model=>view的双向绑定。

不过这种简单绑定不会真正执行obj.txt = e.target.value,因为在setter内部没有保存新值,获取obj.txt时,getter始终返回{}

如果在setter中赋值obj.txt = e.target.value,则会造成无限循环(在setter内部给obj.txt赋值,一修改值又进入setter,又给obj.txt赋值,又进入setter。。。最终栈溢出)。

为了解决这个问题,将Object.defineProperty()封装为一个函数,即可在其中保存状态obj.txt,修改如下:

<body>
    <input type="text" id='input'>
    <span id="show"></span>
</body>
<script>   
    function defineProperty(obj, attr){
        var val;
        Object.defineProperty(obj, attr, {
          get: function(){
              return val
          },
          set: function(newValue){
              if(newValue === val) return;
              val = newValue           
              document.getElementById('input').value = newValue
              document.getElementById('show').innerHTML = newValue
          }
      })
    }

    var obj = {} 
    defineProperty(obj, 'txt')

    document.getElementById('input').addEventListener('keyup', function(e){
       obj.txt = e.target.value
    })
</script>

这就基本实现了一个最简单的双向绑定。

参考:
【JavaScript学习笔记】自己实现双向绑定

你可能感兴趣的:(JavaScript实现一个简单的双向绑定)