1. What is a Proxy? What it does is
  2. get(target, propKey, receiver)
  3. set(target, propKey, value, receiver)
  4. has(target, propKey)
  5. construct(target, args, newTarget)
  6. apply(target, object, args)
  7. Use Proxy to implement simple vUE bidirectional binding
  1. What is a Proxy? What it does is

Proxy can be understood as setting up a layer of “interception” in front of the target object. When the outside world accesses the object, it must go through this layer of interception. Proxy acts as this mechanism, similar to the meaning of Proxy, and it can filter and rewrite the object before accessing it. Extension: Early use of $.proxy to handle proxies

Object.defineproperty () and Proxy objects can both be used to hijack data. What is data hijacking? When we access or modify a property of an object, we intercept it with a piece of code, do something extra, and return the result. Two-way data binding in VUE is a typical application. Vue2. X uses object.defindProperty () to listen on objects. Vue3. X version after the use of Proxy for implementation. Object.defineproperty () is used in vue2.xx to monitor the data of the Object by recursion + traversal. Set () in Object.defineProperty cannot be retriggered when using array methods or changing array subscripts. So you can’t respond in real time. So using Object.defineProperty has the following disadvantages:

  1. Methods that listen on arrays cannot trigger the set operation in object.defineProperty (the array method needs to be rewritten if you want to listen on it).
  2. Each property of each object must be traversed, and recursive calls are required if the objects are deeply nested.

Therefore, in vue3. Xx, we changed to Proxy to better solve the above problems. Before learning how to use Proxy to achieve two-way data binding, we still go step by step and learn the basic knowledge of Proxy first.

Proxy Basic syntax

const obj = new Proxy(target, handler);

Target: indicates the proxy object. Handler: An object that declares some operations for the agent target. Obj: is the object returned after the proxy completes. But every time the outside world operates on obj, it executes some method on the handler object. The common object methods in handler are as follows:

  1. get(target, propKey, receiver)
const target = { name: "proxy", }; Const handler = {get: function (target, key) {console.log(' ${key} is read '); return target[key]; }, set: function (target, key, value) {console.log(' ${key} is set to ${value} '); target[key] = value; }, has: function (target, key) { if (Reflect.has(target, key)) { return true; } else { return false; }}}; const testObj = new Proxy(target, handler); // target: proxied object. // handler: An object that declares some operations for the agent target. // testObj: is the object returned after the proxy completes. console.log("testObj", testObj); Kongzhi console.log(" testobj.name ", testobj.name); kongzhi console.log(" testobj.name ", testobj.name); kongzhi console.log(" testobj.name ", testobj.name);Copy the code
  1. set(target, propKey, value, receiver)

This method is used to intercept the assignment operation of an attribute. It can accept four parameters, which are resolved as follows: target: the target object. PropKey: property name of the target object value: Property value Receiver (Optional): Proxy in general

Testobj. name = "Hello "; console.log("target.name", target.name); // Target is a proppant object, handler is a proppant target, handler is a proppant target, handler is a proppant target, handler is a proppant target, handler is a proppant target, handler is a proppant target, handler is a proppant target, handler is a proppant target, handler is a proppant target. Every time when the set target. Name attribute value, will automatically call set method in the handler, so the target object corresponding to the attribute values will change, and change after testObj object will also change. // If the testObj object is of the same type as the testObj object, the testObj object is of the same type as the testObj object. // A pointer to an object is stored in stack memory. This pointer points to the object's storage address in heap memory. Copying to another object actually copies the address of that object to another object variable. Both Pointers point to the same object, so if one changes, the other changes. Writable: false, set a property of the target object itself is not writable, then the set method will not work.Copy the code
  1. has(target, propKey)

This method determines whether a target object has the property name. Receives two parameters, the target object and the property name. It returns a Boolean.

const obj = { 'name': 'kongzhi' }; const handler = { has: function(target, key) { if (Reflect.has(target, key)) { return true; } else { return false; }}}; const proxy = new Proxy(obj, handler); console.log(Reflect.has(obj, 'name')); // true console.log(Reflect.has(obj, 'age')); // falseCopy the code
  1. construct(target, args):

This method is used to intercept the new command, which takes three arguments: the target object, the constructor’s argument object, and the object that created the real column. The third parameter is optional. It intercepts object properties.

function A(name) { this.name = name; Const handler = {construct: function(target, args, newTarget) {/* Output: function A(name) {this.name = name; } */ console.log(target); // Output: ['kongzhi', {age: 30}] console.log(args); return args } }; const Test = new Proxy(A, handler); const obj = new Test('kongzhi', {age: 30}); console.log(obj); ['kongzhi', {age: 30}]Copy the code
  1. apply(target, object, args)

This method intercepts a function call. This method takes three parameters, the target object. Target object context This object and an array of target objects; It is the same as the reflect. apply parameter

var target = function () { return "I am the target"; }; var handler = { apply: function () { return { msg: '"I am the proxy"' }; }}; var p = new Proxy(target, handler); p(); console.log(p); console.log(p()); // The variable p is an instance of Proxy. When called as a function (p()), it is intercepted by apply and returns a string.Copy the code

Use proxy to implement vUE data bidirectional binding

<! 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 =1.0" /> <title>Document</title> </head> <body> <div id="app"> <h3 id="value"></h3> <input type="text" id="input" /> </div> </body> <script> const demo = document.getElementById("value"); const input = document.getElementById("input"); const data = { text: "hello", msg: "vue", }; const handler = { set: function (target, prop, value) { console.log(target, prop, value); if (prop === "text") { target[prop] = value; demo.innerHTML = value; return true; } else { return false; }}}; const myTest = new Proxy(data, handler); input.addEventListener( "input", (e) => { myTest.text = e.target.value; }, false ); </script> </html>Copy the code