vue data bidirectional binding principle, but this method has shortcomings and cannot implement partial monitoring of arrays and objects; you can also see a blog I wrote before: About Vue's solution to the change of arrays and objects. Compared with vue2, the latest Proxy can achieve the results of double speed and halving memory. How to implement it and why the old implementation methods can have the characteristics of double speed and halving memory. Let’s talk about it below:
Vue initialization process
The initialization process of Vue includes Observer, Compiler and Watcher. When we new Vue, we will call Observer and listen by traversing all properties of the data, computed or props (if it is a component). At the same time, the template instructions are parsed through Compiler. After parsing the attribute, a Watcher is new and the update function is bound to the watcher. Observer and Compiler are associated through attributes.
Let's have a simple example
class Observer { constructor(data) { // traverse the attributes of the parameter data and add them to this for (let key of (data)) { if (typeof data[key] === "object") { data[key] = new Observer(data[key]); } (this, key, { enumerable: true, configurable: true, get() { ("You visited" + key);//You visited the age return data[key];//20 }, set(newVal) { ("You set it" + key); //You have set the age ("New" + key + "=" + newVal); //New age=20 if (newVal === data[key]) { return; } data[key] = newVal; } }); } } }const obj = { name: "app", age: "18", a: { b: 1, c: 2, } };const app = new Observer(obj); = 20;(); = "New Attributes";(); //New properties
From the above, we can know that all attributes need to be traversed, which causes if the data in data/computed/props of the vue object is huge, then it will be much slower to traverse. Similarly, if the data in data/computed/props of the vue object is huge, then it needs to listen for changes in all attributes, and then it will take up a lot of memory.
Proxy
Let's take a look at proxy
Proxy objects are used to define custom behaviors for basic operations (such as property search, assignment, enumeration, function calls, etc.)
It can be understood that a "intercept" is set before the object. When the listening object is accessed, it must pass through this layer of interception. The original object can be processed in this interception and the required data format is returned, that is, no matter what attributes of the object are accessed, previously defined or newly added attributes, they will go to the interception for processing. This solves the problem that was not able to monitor before.
const obj = { name: "krry", age: 24, others: { mobile: "mi10", watch: "mi4", },};const p = new Proxy(obj, { get(target, key, receiver) { ("The property viewed is:" + key); return (target, key, receiver); }, set(target, key, value, receiver) { ("The properties set are:" + key); ("New properties:" + key, "Value is:" + value); (target, key, value, receiver); },}); = 22;(); = "NO";(); = "boost";();The output result is:The properties set are:age New properties:age The value is:22The properties viewed are:age22 The properties set are:single New properties:single The value is:NOThe properties viewed are:singleNO The properties viewed are:others The properties viewed are:others boost
From the above, we can see that adding or editing attributes does not require responsive processing to be added, and they can be listened to, because Proxy is an operation on an object. As long as you access the object, you will enter the logic of Proxy. Reflect is a built-in object that provides methods to intercept JavaScript operations. These methods are the same as those of proxy handlers. Reflect is not a function object, so it is not constructable. The usage methods of distinguishing Proxy and , seem very similar. In fact, Proxy intercepts attributes in a higher dimension.
In Object.definePropertyVue2, for a given data: such as { count: 1 }, you need to intercept get and set according to the specific key, that is:
(data, 'count', { get() {}, set() {},})
You must know in advance what the key to intercept is, which is why Vue2 is powerless to add new attributes on the object, so during the initialization of Vue, data needs to be traversed to hold data changes, resulting in slower speed and larger memory.
Proxy and the Proxy used by Vue3 are intercepted like this:
new Proxy(data, { get(key) { }, set(key, value) { },})
It can be seen that proxy does not need to care about specific keys. It intercepts are to modify any key on data and read any key on data.
Therefore, whether it is an existing key or a new key, it will be monitored.
This is the article about the reason why Vue3 uses Proxy to implement data monitoring. For more information about why Vue3 uses Proxy to implement data monitoring, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!