• 比较Vue2与Vue3的响应式


    1 vue2

    Vue2.0中使用ES5中的Object.defineProperty方法实现响应式数据
    缺点
    无法监测到对象属性的动态添加和删除
    无法监测到数组的下标和length属性的变更
    解决方案
    Vue2.0提供Vue.set方法用于动态给对象添加属性
    Vue2.0提供Vue.delete方法用于动态删除对象的属性
    重写vue中数组的方法,用于监测数组的变更

      <body>
        <script>
          // vue会做一个数据劫持,,,监视数据的变化,一旦数据变化了,更新DOM
          const data = {
            name: 'zs',
            age: 18
          }
          for (let k in data) {
            let temp = data[k]
            Object.defineProperty(data, k, {
              get() {
                console.log(`我劫持了${k}的获取`)
                return temp
              },
              set(value) {
                console.log(`我劫持了${k}的设置,值${value}`)
                temp = value
              }
            })
          }
          // Object.defineProperty有缺点
          // 1. 无法监视到新增的属性的变更和删除
          // 2. 无法劫持到数组的下标和长度
        </script>
      </body>
    
      <body>
        <div id="app">
          <h1>vue的例子</h1>
          <p>{{car.brand}} --- {{car.color}} ---{{car.price}}</p>
          <p>{{arr}}</p>
        </div>
        <script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
        <script>
          // vue中需要使用$set方法动态的增加一个响应式属性
          const vm = new Vue({
            el: '#app',
            data: {
              car: {
                brand: '奔驰',
                color: 'blue'
              },
              arr: ['张三', '李四']
            }
          })
        </script>
      </body>
    

    2 vue3

    通过Proxy(代理): 拦截对data任意属性的任意(13种)操作, 包括属性值的读写, 属性的添加, 属性的删除等...
    通过 Reflect(反射): 动态对被代理对象的相应属性进行特定的操作
    Vue3.0中使用ES6中的proxy语法实现响应式数据
    优点
    可以检测到代理对象属性的动态添加和删除
    可以监测到数组的下标和length属性的变更
    缺点
    ES6的proxy语法对于低版本浏览器不支持,IE11
    Vue3.0会针对于IE11出一个特殊的版本用于支持ie11

      <body>
      <div></div>
      <script>
        const data = {
          name: 'zs',
          age: 18
        }
        // 能够监测到对象动态新增的属性以及删除的属性
        // proxy
        const proxyData = new Proxy(data, {
          get(target, name) {
            console.log(`检测到${name}的获取`)
            return target[name]
          },
          set(target, name, value) {
            console.log(`检测到${name}的设置,值为${value}`)
            target[name] = value
          },
          deleteProperty(target, key) {
            console.log(`监测到删除${key}`)
            return delete target[key]
          }
        })
      </script>
    </body>
    
      <body>
      <div id="app">
        <h1>vue的例子</h1>
        <p>{{car.brand}} --- {{car.color}} ---{{car.price}}</p>
        <p>{{arr}}</p>
      </div>
      <script src="https://unpkg.com/vue@next"></script>
      <script>
        const App = {
          data() {
            return {
              car: {
                brand: '宝马',
                color: 'green'
              },
              arr: ['张三', '李四']
            }
          },
          methods: {
            fn() {
              this.car.brand = '奔驰'  //不再需要vue2中的$set方法就用代理更新
              // 会在DOM更新后才会执行回调函数
              nextTick(function () {
                // vue为了性能考虑,不会改变完数据就立即更新DOM
                console.log(document.querySelector('p').innerHTML)
              })
            }
          }
        }
        const vm = Vue.createApp(App).mount('#app')
      </script>
    </body>
    
    new Proxy(data, {
      // 拦截读取属性值
      get (target, prop) {
      	return Reflect.get(target, prop)
      },
      // 拦截设置属性值或添加新属性
      set (target, prop, value) {
      	return Reflect.set(target, prop, value)
      },
      // 拦截删除属性
      deleteProperty (target, prop) {
      	return Reflect.deleteProperty(target, prop)
      }
    })
    
    proxy.name = 'tom'   
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Proxy 与 Reflect</title>
    </head>
    <body>
      <script>
        
        const user = {
          name: "John",
          age: 12
        };
    
        /* 
        proxyUser是代理对象, user是被代理对象
        后面所有的操作都是通过代理对象来操作被代理对象内部属性
        */
        const proxyUser = new Proxy(user, {
    
          get(target, prop) {
            console.log('劫持get()', prop)
            return Reflect.get(target, prop)
          },
    
          set(target, prop, val) {
            console.log('劫持set()', prop, val)
            return Reflect.set(target, prop, val); // (2)
          },
    
          deleteProperty (target, prop) {
            console.log('劫持delete属性', prop)
            return Reflect.deleteProperty(target, prop)
          }
        });
        // 读取属性值
        console.log(proxyUser===user)
        console.log(proxyUser.name, proxyUser.age)
        // 设置属性值
        proxyUser.name = 'bob'
        proxyUser.age = 13
        console.log(user)
        // 添加属性
        proxyUser.sex = '男'
        console.log(user)
        // 删除属性
        delete proxyUser.sex
        console.log(user)
      </script>
    </body>
    </html>
    
  • 相关阅读:
    99%的人没使用过它俩,Docker最佳实践+2
    kubernetes 中 kubeconfig 的用法
    jenkins批量修改配置文件
    记一次K8s排错实战
    记一次失败记录: MindSpore1.3.0 GPU 源码安装 —— Ubuntu18.04系统 (最终安装结果为失败)
    【转载】 使用Python的ctypes查看内存
    (摘抄) 源码分析multiprocessing的Value Array共享内存原理
    (续) python 中 ctypes 的使用尝试
    python 中 ctypes 的使用尝试
    深度强化学习算法(深度强化学习框架)为考虑可以快速适用多种深度学习框架建议采用弱耦合的软件设计方法——快速适用于多种深度学习计算框架的深度强化学习框架设计方案
  • 原文地址:https://www.cnblogs.com/xm0328/p/14278112.html
Copyright © 2020-2023  润新知