Writing in the front

If you know anything about reactive implementations of Vue publish subscriptions, you know defineProperty.

Object.defineProperty(obj, prop, descriptor)

The reactive implementation in vue2. x is implemented through getter and setter listening for attributes based on defineProperty descriptor.

Also, you should know that we can’t do setter listening in Vue by subscripting property values or adding a preexisting object property, which is a limitation of defineProperty.

The push, pop, Shift, unshift, splice and other methods used in Vue to modify the original array are actually not native array methods. They are all modified by Vue with response code added.

It is said that the responsiveness of Vue3.0 will be implemented by Proxy. This move will undoubtedly optimize the responsiveness of Vue, but it also determines that Vue will completely abandon the IE camp. Should we be sad for a minute?

Getters, setters in defineProperty

The biggest reason for defineProperty’s limitations is that it can only listen for singleton attributes. In Vue2. X, attributes in data are traversed + recursed, and getters and setters are set for each attribute.

This is why Vue can only respond to predefined attributes in Data.

The use of the defineProperty

    var val = 1
    var obj = Object.defineProperty({}, 'sum', {
        enumerable: true.configurable: true,
        get() {
            return val
        },
        set(newValue) {
            val += newValue
        }
    })
Copy the code

Test code:

We could also write:

    var val = 1
    var obj = {
        get ['sum'] () {return val
        },
        set ['sum'](newValue) {
            val += newValue
        }
    }
Copy the code

This code is the same as the code above.

Here ‘sum’ is the name of the property being listened on, that is, the ‘one’ property that we need to listen on.

Because you can only bind one attribute listener at a time using defineProperty, Vue has a higher performance cost and more code when traversing + recursion.

Getters and setters in Proxy

Vue3.0 is finally going to use Proxy. As mentioned above, the first thing you should do is lament IE.

Proxy can be understood as a layer of “interception” before the target object. All external access to the object must pass this layer of interception. Therefore, Proxy provides a mechanism for filtering and rewriting external access.

In other words, the Proxy listens on an object, so all operations on that object go into the listening operation, which can completely Proxy all properties.

More usage of Proxy can be seen in Ruan Yifong ES6 introduction -Proxy, this article only explains getter, setter implementation.

Using a Proxy to listen

    var data = {
        sum: 0
    }
    var proxy = new Proxy(data, {
        get(target, property) {
            return target[property]
        },
        set(target, property, value) {
            target[property] += value
        }
    })
Copy the code

The Proxy test

When data is an array:

Description of getters and setters in Proxy

Get receives three parameters: get(target, propKey, receiver)

PropKey is the property name, that is, the property name to be obtained currently. Receiver is the listening object, that is, the Proxy instance, that is, the Proxy in the example code

Set accepts four arguments: get(target, propKey, value, receiver)

The target, propKey, and Receiver parameters are the same as those in GET. Value indicates the modified value, that is, 1 in the test code

Obviously, we don’t need to care about a specific attribute when using a Proxy, and changes to the Proxy instance don’t affect the value in the target object (as long as you don’t actively modify the target).

Limitations of getters and setters in Proxy

Let’s look at the following code:

    var data = {
        a: { b: 0}}var proxy = new Proxy(data, {
        get(target, property) {
            console.log(`path: ${property}`)
            return target[property]
        },
        set(target, property, value) {
            console.log(`path: ${property}`)
            target[property] += value
        }
    })
Copy the code

Print result:

Obviously, proxy getters and setters focus only on shallow data and do not return deep paths.

It would be nice if PATH could return A.B here, but since the Proxy specification is not implemented there is nothing we can do about it.

It seems to be correct to change the name of proxy.a.b to a. Now we just need to remember this conclusion.

conclusion

So much for getters and setters in Proxy and defineProperty.

Predictably, the use of Proxy proxies in Vue3.0 will result in significant performance improvements and better code.

But as agreed in React, responsive support for reference type values may become even less friendly than before (requiring developers to implement shallow-copy assignments).

However, if Utah still chooses to use a recursive approach to solve the object type data response, I personally think it is not worth the loss.

For my own sake, I prefer immutable rather than the old way of recursive traversal.

I believe that THE University of Utah will have its own considerations, and the final result will surely be a plan that satisfies most people.

I’m also excited about the direction of typescript support for Vue3, and as a fan, we have a lot to look forward to.