This is the 30th day of my participation in the August Challenge
Using Proxy simulation to implement Vue 3.0 responsive system. The code is as follows:
// Determine if a value is an object's helper method
function isObject(val){
returnval ! = =null && typeof val === 'object'
}
// Reactive core methods
function reactive(target){
return createReactiveObject(target)
}
// A method to create a responsive object
function createReactiveObject(target){
// If target is not an object, return it directly
if(! isObject(target)){return target
}
const baseHandler = {
get(target, property, receiver){
console.log('Get value')
const result = Reflect.get(target, property, receiver)
return result
},
set(target, property, value, receiver){
console.log('Set value')
const result = Reflect.set(target, property, value, receiver)
return result
},
deleteProperty(target, property){
return Reflect.deleteProperty(target, property)
}
}
}
const proxy = reactive({name:'jack'})
proxy.name = 'tom'
console.log(proxy.name)
Copy the code
Reflect is a built-in object that provides methods to intercept JavaScript operations. Each proxy trap corresponds to a Reflect method with the same name and parameters. The above code runs as follows:
Set value Gets the value TomCopy the code
Also, to solve the multi-layer object detection problem, we need to make a judgment on the return value in the GET trap function. If the return value is an object, we create a proxy object for the return value, which is also a recursive call.
Modify the get trap function to judge the return value, the code is as follows:
// ...
// A method to create a responsive object
function createReactiveObject(target){
// ...
const baseHandler = {
get(target, property, receiver){
console.log('Get value')
const result = Reflect.get(target, property, receiver)
// Perform recursive processing on the object
return isObject(result) ? reactive(result) : result
},
set(target, property, value, receiver){
console.log('Set value')
const result = Reflect.set(target, property, value, receiver)
return result
},
// ...}}const proxy = reactive({name:'vue.js'.address: {city: 'Beijing'}})
proxy.address.city = 'tianjin'
Copy the code
Access to proxy.address causes a get trap call, and since the address property is itself an object, code is created for that property as well.
The above code runs as follows:
Get Value Set valueCopy the code
The code on the same target agent for many times, if you return a different proxy objects, there is no point, to solve this problem, after can create proxy for target for the first time, is the key with the target object, the agent for the value, save to a Map, and then in before each create agency, to determine the target object, If a proxy object already exists, it is returned without creating a new proxy object.