Vue学习计划-Vue3--核心语法(十)Proxy响应式原理

Proxy响应式原理
1.Vue2的响应式
  • 实现原理:
    • 对象类型:通过Object.defineProperty()对属性的读取、修改进行拦截(数据劫持)
    • 数组类型:通过重写更新数组的一系列方法来实现拦截,(对数组的变更方法进行了包裹)
    Object.defineProperty(data, 'count', {
      get(){},
      set(){}
    })
    
  • 存在问题:
    • 新增属性、删除属性,界面不会更新

    解决方式: this.$set()\Vue.set()this.$delete()\Vue.delete()

    • 直接通过下标修改数组,界面不会更新

    解决方式: this.$set()\Vue.set(),Array.splice(0,1,‘demo’)

2. Vue3的响应式(Proxy)
  1. 示例Proxy
<script>
let data = {
  name: '张三',
  age: 19
}
// 模拟Vue3响应式
const p = new Proxy(data, {
  // 接收参数 target:传入对象, propName: 读取到的具体属性名
  // 有人读取了某个属性
  get(target, propName){
    console.log(`有人读取了p身上的${propName}属性`,target, propName)
    return target[propName]
  },
  // 有人修改了p的某个属性、或新增某个属性
  set(target, propName, value){
    console.log(`有人修改或新增了p身上的${propName}属性`)
    target[propName] = value
  },
  // 有人删除某个属性
  deleteProperty(target, propName){
    console.log(`有人删除了p身上的${propName}属性`)
    return delete target[propName]
  }
})
</script>

效果图:
在这里插入图片描述

  1. 示例Reflect:
  1. Reflect.get(target, propertyKey[, receiver])
    获取对象身上某个属性的值,类似于 target[name]
  2. Reflect.set(target, propertyKey, value[, receiver])
    将值分配给属性的函数。返回一个Boolean,如果更新成功,则返回true。
  3. Reflect.deleteProperty(target, propertyKey)
    作为函数的delete操作符,相当于执行 delete target[name]
  4. Reflect.defineProperty(target, propertyKey, attributes)
    Object.defineProperty() 类似。如果设置成功就会返回 true

举个例子:

<script>
  let data = {
    name: '小明'
  }
  // Object.defineProperty操作, 重复定义会报错,不能继续往下执行,检验错误写在try...catch中
  // Object.defineProperty(data, 'age',{
  //   get(){
  //     return 19
  //   }
  // })
  // Object.defineProperty(data, 'age',{
  //   get(){
  //     return 20
  //   }
  // })
  // Reflect操作,直接返回Boolean,不会打断运行
  let x1 = Reflect.defineProperty(data, 'age',{
    get(){
      return 19
    }
  })
  console.log(x1)
  let x2 = Reflect.defineProperty(data, 'age',{
    get(){
      return 20
    }
  })
  console.log(x2)
  if(x1){
    console.log('设置成功')
  } else{
    console.log('设置失败')
  }
  console.log('@@@')
</script>

3.所以模拟Proxy响应:

// 模拟Vue3响应式
const p = new Proxy(data, {
  // 接收参数 target:传入对象, propName: 读取到的具体属性名
  // 有人读取了某个属性
  get(target, propName){
    console.log(`有人读取了p身上的${propName}属性`,target, propName)
    // return target[propName]
    return Reflect.get(target, propName)
  },
  // 有人修改了p的某个属性、或新增某个属性
  set(target, propName, value){
    console.log(`有人修改或新增了p身上的${propName}属性`)
    // target[propName] = value
    return Reflect.set(target, propName, value)
  },
  // 有人删除某个属性
  deleteProperty(target, propName){
    console.log(`有人删除了p身上的${propName}属性`)
    // return delete target[propName]
    return Reflect.deleteProperty(target, propName)
  }
})
posted @   化作繁星  阅读(134)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示