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>

    .

  • 相关阅读:
    30 Day Challenge Day 4 | Leetcode 102. Binary Tree Level Order Traversal
    30 Day Challenge Day 4 | Hackrank
    30 Day Challenge Day 4 | Leetcode 104. Maximum Depth of Binary Tree
    30 Day Challenge Day 3 | Leetcode 145. Binary Tree Postorder Traversal
    30 Day Challenge Day 3 | Leetcode 144. Binary Tree Preorder Traversal
    30 Day Challenge Day 2 | Leetcode 1302. Deepest Leaves Sum
    30 Day Challenge Day 2 | Leetcode 206. Reverse Linked List
    30 Day Challenge Day 1 | Leetcode 107. Binary Tree Level Order Traversal II
    30 Day Challenge Day 1 | Hackerrank
    刷题 | Leetcode 901. Online Stock Span | Stack
  • 原文地址:https://www.cnblogs.com/crazycode2/p/13458160.html
Copyright © 2011-2022 走看看