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

发布时间:2024年01月16日
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)
  }
})
文章来源:https://blog.csdn.net/qq_35940731/article/details/135590976
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。