关于两种简单的双向绑定

113 阅读1分钟

基于Object.defineProperty的绑定方法

通过监听对象的数据的变化来改变页面

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <h1>极度简单的双向绑定</h1>
  <input type="text" id="model"><br>
  要被更改的数据<br>
  <div id="modelVal"></div>
  <script>
    let bindObject = new Object()
    let model = document.querySelector('#model')

    Object.defineProperty(bindObject, 'model', {
      get() {
        return value
      },
      set(newVal) {
        value = newVal
        // 修改数据
        setValue(value)
      }
    })

    function setValue(value) {
      model.value = value
      document.querySelector('#modelVal').innerHTML = value
    }

    model.addEventListener('keyup', (e) => {
      // 监听输入框数据改变的时候,触发bindObject数据改变
      bindObject.model = e.target.value
    })
  </script>
</body>
</html>

基于Proxy()的绑定方法

通过监听对象的变化来改变页面

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>标题</title>
</head>

<body>
  <h1>极度简单的双向绑定</h1>
  <input type="text" id="model"><br>
  要被更改的数据<br>
  <div id="modelVal"></div>

  <script type="text/javascript">
    let bindObject = new Object()
    let model = document.querySelector('#model')
    // new Proxy(target, handler = {})
    // target: 要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)
    // handler: 一个通常以函数作为属性的=>对象<=

    // 转化对象为Proxy对象
    bindObject = new Proxy(bindObject, {
      get(target, key) {
        return target[key]
      },

      set(target, key, value) {
        // return true表示成功

        // Reflect.set(target, propertyKey, value)
        /**
         * target:设置属性的目标对象。
         * propertyKey:设置的属性的名称。
         * value:设置的值。
         * 成功 return true
         * 失败 抛出异常
         */
        let refl = Reflect.set(target, key, value)
        setValue(value)
        return refl
      }
    })

    function setValue(value) {
      model.value = value
      document.querySelector('#modelVal').innerHTML = value
    }

    model.addEventListener('keyup', (e) => {
      // 监听输入框数据改变的时候,触发bindObject数据改变
      bindObject.model = e.target.value
    })
  </script>
</body>
</html>