当把一个普通的 JavaScript 对象作为 data 选项传给应用或组件实例的时候,Vue 会使用带有 getter 和 setter 的处理程序遍历其所有 property 并将其转换为 Proxy。这是 ES6 仅有的特性,但是我们在 Vue 3 版本也使用了 Object.defineProperty 来支持 IE 浏览器。两者具有相同的 Surface API,但是 Proxy 版本更精简,同时提升了性能。
点击此处实现
该部分需要稍微地了解下 Proxy 的某些知识!所以,让我们深入了解一下。关于 Proxy 的文献很多,但是你真正需要知道的是 Proxy 是一个包含另一个对象或函数并允许你对其进行拦截的对象。
我们是这样使用它的:new Proxy(target, handler)
const dinner = {
meal: 'tacos'
}
const handler = {
get(target, prop) {
return target[prop]
}
}
const proxy = new Proxy(dinner, handler)
console.log(proxy.meal)
// tacos
好的,到目前为止,我们只是包装这个对象并返回它。很酷,但还不是那么有用。请注意,我们把对象包装在 Proxy 里的同时可以对其进行拦截。这种拦截被称为陷阱。
const dinner = {
meal: 'tacos'
}
const handler = {
get(target, prop) {
console.log('intercepted!')
return target[prop]
}
}
const proxy = new Proxy(dinner, handler)
console.log(proxy.meal)
// tacos
除了控制台日志,我们可以在这里做任何我们想做的事情。如果我们愿意,我们甚至可以不返回实际值。这就是为什么 Proxy 对于创建 API 如此强大。
此外,Proxy 还提供了另一个特性。我们不必像这样返回值:target[prop],而是可以进一步使用一个名为 Reflect 的方法,它允许我们正确地执行 this 绑定,就像这样:
const dinner = {
meal: 'tacos'
}
const handler = {
get(target, prop, receiver) {
return Reflect.get(...arguments)
}
}
const proxy = new Proxy(dinner, handler)
console.log(proxy.meal)
// tacos |