Object.defineProperty()手写一个双向绑定示例

103 阅读1分钟
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Object.defineProperty()手写一个双向绑定示例</title>
  <style>
    * {
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }

    #modelText {
      padding: 6px;
      margin-top: 20px;
      border: 1px solid #dedede;
    }
  </style>
</head>

<body>
  <label for="model">请输入内容:<input type="text" id="model"></label>
  <div id="modelText"></div>
  <script>
    // 获取元素
    const model = document.querySelector('#model');
    const modeText = document.querySelector('#modelText');
    // 定义默认值
    let defaultText = 'defaultText';
    const returnData = {};
    let lock = true;
    // 赋值
    model.value = defaultText;
    modelText.textContent = defaultText;
    returnData.testValue = defaultText;
    // 修改对象属性
    Object.defineProperty(returnData, 'testValue', {
      get: function () {
        console.log('获取值',);
        return defaultText;
      },
      set: function (value) {
        console.log('设置取值', value);
        defaultText = value;
        // 模型到视图  model => view
        model.value = value;
        modelText.textContent = value;
      }
    });
    // 监听事件 键盘按键弹起
    model.addEventListener('keyup', function () {
      // 视图到模型 view => model
      if (lock) { returnData.testValue = this.value; }
    });

    // 监听事件 中文输入开始
    model.addEventListener('compositionstart', function () { console.log('中文输入开始'); lock = false; });

    // 监听事件 中文输入结束
    model.addEventListener('compositionend', function () { console.log('中文输入结束'); lock = true; });
  </script>
</body>

</html>