Vue3 使用了 Proxy,啊?你还没用过 Proxy......

246 阅读2分钟

记录学习的博客

Vue3 放弃了 defineProperty 使用 Proxy 来代替
可是,我一直没使用过 Proxy,所以,我来学习一下 Proxy 的基本用法,并写一篇博客记录一下

以免我以后忘了

是什么

  1. 是 ES6 原生 API
  2. 作用:用来更改对象默认方法(理解:在目标对象之前架设一层「拦截」),外界对该对象的访问,都必须先通过这层拦截
  3. 机制:可以对外界的访问进行过滤和改写
  4. 等同:在语言层面做出修改 —— 「代理器」

怎么写

语法

let p = new Proxy(target, handler)

参数

target:使用 Proxy 包装的目标对象「任意类型」

handler:通常是函数,定义了拦截的行为(执行各种操作时,p 的行为)

例子:自定义 getter setter

1. 对象会写吧?

let foo = {
  name: 'heycn',
  sayHi: '你们好呀'
}
console.log(foo.sayHi)

上面 foo.sayHi,其实就是一个属性的读取,这就是一个 get,我们把它拦截一下

2. get 方法

get 用于拦截某个属性的读取操作

接受 3 个参数:目标对象 属性名 Proxy 实例本身(可选)

// 普通对象
let foo = {
  name: 'heycn',
  sayHi: '你们好呀'
}
console.log(foo.sayHi)

// Proxy 拦截行为
let _handler = {
  get: function (target, _p) {
    if (target.name === 'heycn') {
      return '我是 heycn'
    }
  }
}

// Proxy 对象
let p = new Proxy(foo, _handler)
console.log(p.name)

3. set 方法

set 用来拦截某个属性的 赋值 的操作

接收 4 个参数:目标对象 属性名 属性值 Proxy 实例本身(可选)

// 普通对象
let foo = {
  name: 'heycn',
  sayHi: '你们好呀'
}
console.log(foo.sayHi)

// Proxy 拦截行为
let _handler = {
  get: function (target, _p) {
    if (target.name === 'heycn') {
      return '我是 heycn'
    }
  },
  set: function (_obj, _prop, _val) {
    if (_prop === 'sayHi') {
      _obj[_prop] = '我在 get 里面,听说你想改我?' // 只要改了 p.sayHi 对象 里的属性值,我就执行
    }
  }
}

// Proxy 对象
let p = new Proxy(foo, _handler)
console.log(p.name)

p.sayHi = '嘿嘿被我修改了' // 我一改就会被拦截,set 里代理赋值
console.log(p)

输出结果:

image.png

讲一下

Object.defineProperty 和 ES6 的 Proxy 用法/思路 是一样的