Vue中的数据代理理解

285 阅读1分钟

image.png 普通的数据代理(数据劫持)就是利用Object.defineProperty()来给对象添加属性值或者修改某值,数据代理是通过一个对象代理对另一个对象中的属性进行操作,在Vue中是将data中的属性代理到了Vue实例中,并将data数据存放到了_data中进行保存。但是它不支持监听数组的变化,Vue 2.x 使用的是 Object.defineProperty()(Vue 在 3.x 版本之后改用 Proxy 进行实现

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数据代理</title>
    <!-- 数据代理是通过一个对象代理对另一个对象中的属性进行操作 -->
</head>

<body>
    <script>
        let obj1 = {
            x: 100
        }
        let obj2 = {
            y: 300
        }
        Object.defineProperty(obj2, 'x', {
            get() {
                return obj1.x
            },
            set(value) {
                obj1.x = value
            }
        })
    </script>
</body>

</html>

Proxy

Proxy 在 ES2015 规范中被正式加入,它的支持度虽然不如 Object.defineProperty(),但其实也基本支持了 (除了 IE 和 Opera Mini 等少数浏览器,所以使用起来问题也不太大。 在数据劫持这个问题上,Proxy 可以被认为是 Object.defineProperty() 的升级版。外界对某个对象的访问,都必须经过这层拦截。因此它是针对 整个对象,而不是 对象的某个属性,所以也就不需要对 keys 进行遍历。这解决了上述 Object.defineProperty() 的第二个问题。并且支持数组。

    let obj = {
 name: 'Eason',
 age: 30
 }

 let handler = {
 get (target, key, receiver) {
 console.log('get', key)
 return Reflect.get(target, key, receiver)
 },
 set (target, key, value, receiver) {
 console.log('set', key, value)
 return Reflect.set(target, key, value, receiver)
 }
 }
 let proxy = new Proxy(obj, handler)

 proxy.name = 'Zoe' // set name Zoe
 proxy.age = 18 // set age 18


 
  let arr = [1,2,3]

  let proxy = new Proxy(arr, {
  get (target, key, receiver) {
  console.log('get', key)
  return Reflect.get(target, key, receiver)
  },
  set (target, key, value, receiver) {
  console.log('set', key, value)
  return Reflect.set(target, key, value, receiver)
  }
  })

  proxy.push(4)
  // 能够打印出很多内容
  // get push (寻找 proxy.push 方法)
  // get length (获取当前的 length)
  // set 3 4 (设置 proxy[3] = 4)
  // set length 4 (设置 proxy.length = 4)