zoukankan      html  css  js  c++  java
  • vue 双向数据绑定的原理

    vue2.0 通过ES5: Object.defineProperty

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>vue2.0 数据双向绑定</title>
      </head>
      <body>
        姓名:<span id="spanName"></span>
        <br />
        <input type="text" id="inpName" />
    
        <script>
          /**
           * 通过ES5: Object.defineProperty
           * 数据改变,触发视图重新渲染。视图改变,触发数据改变。
           */
          let obj = {
            name: "",
          };
          /**
           * 简单实现深克隆
           * 接收改变后的值,避免死循环
           */
          let newObj = JSON.parse(JSON.stringify(obj));
    
          // 监听 obj 中 name 值的改变
          Object.defineProperty(obj, "name", {
            get() {
              return newObj.name; // 通过新的变量接收改变后的值,避免出现死循环的情况
            },
            set(val) {
              if (val === newObj.name) return;
              newObj.name = val;
              observer();
            },
          });
    
          // 观察者
          function observer() {
            spanName.innerHTML = obj.name; // 获取 obj值的时候会触发 get() 获取最新的值
            inpName.value = obj.name;
          }
    
          // observer();
    
          /**
           * 模拟修改数据
           * 数据的更改影响视图
           */
          setTimeout(() => {
            obj.name = "测试";
          }, 1000);
    
          /**
           * 监听 input 文本框的改变
           * 视图的改变影响数据
           * 相当于 v-model
           */
          inpName.oninput = function () {
            obj.name = this.value;
          };
    
          /**
           * 存在的问题:
           * 1.需要对原始数据进行克隆
           * 2.需要分别给对象中每一个属性设置监听
           */
        </script>
      </body>
    </html>

    vue3.0 通过ES6 Proxy 拦截器实现数据双向绑定

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>vue3.0 实现数据的双向数据绑定</title>
      </head>
      <body>
        姓名:<span id="spanName"></span>
        <br />
        <input type="text" id="inpName" />
    
        <script>
          /**
           * 通过ES6 Proxy 拦截器实现数据双向绑定
           * 1.不需要克隆
           * 2.不需要对对象的每个属性设置监听
           */
          let obj = {};
          /**
           * 监听整个对象
           * 不需要指定属性
           * 把当前对象的所有属性都监听(截持)了
           */
          obj = new Proxy(obj, {
            get(target, prop) {
              // target 就是 obj
              return target[prop];
            },
            set(target, prop, value) {
              target[prop] = value;
              observer();
            },
          });
    
          // 观察者
          function observer() {
            spanName.innerHTML = obj.name; // 获取 obj值的时候会触发 get() 获取最新的值
            inpName.value = obj.name;
          }
    
          /**
           * 模拟修改数据
           * 数据的更改影响视图
           */
          setTimeout(() => {
            obj.name = "测试";
          }, 1000);
    
          /**
           * 监听 input 文本框的改变
           * 视图的改变影响数据
           * 相当于 v-model
           */
          inpName.oninput = function () {
            obj.name = this.value;
          };
        </script>
      </body>
    </html>

    .

  • 相关阅读:
    IE hack [if IE]解决IE CSS 兼容问题
    jQuery重要插件、JS辅助工具
    几个jQueryUI框架
    推荐书籍
    Win7下用原生的ie6调试网页
    Code First :使用Entity. Framework编程(3)
    Code First :使用Entity. Framework编程(6)
    JSON数据格式转换
    Code First :使用Entity. Framework编程(5)
    Code First :使用Entity. Framework编程(4)
  • 原文地址:https://www.cnblogs.com/crazycode2/p/13458160.html
Copyright © 2011-2022 走看看