Writing in the front

At the heart of data-driven views is the Vue responsive principle, which automatically helps developers listen for changes in data and ultimately triggers view updates. It is at the heart of Vue’s render update process. So it is very important to understand the principle of this part, this article is combined with vue2 and VUe3 response formula to do a comparison, not only understand the implementation of the response type principle, but also compare the difference between the two in performance ~

Need to knowapi

This article is not zero foundation, need to have a certain understanding of some basic API, so here is the official documentation of these apis, for your reference.

  • Vue2 response formula principle

Object.defineProperty

  • Vue3 response principle

Proxy

Reflect

Prepare a raw object data

To do this experiment, I use the same data object to do vue2 and VUe3 separately: Note that there are eight levels of data from the outermost bracket to the innermost, and you can count them.

const data = {
    username: 'tom'.profile: {
        city: 'beijing'.a: {
            b: 12.c: {
                d: 23}}}}Copy the code

Next, I’ll write some code to respond to this data:

  • vue2
const data = {
    username: 'tom'.profile: {
        city: 'beijing'.a: {
            b: 12.c: {
                d: 23}}}}function observe(data) {
    console.log(1);
    if (typeofdata ! = ='object' || data == null) {
        return data
    }
    for (const key in data) {
        defineReactive(data, key, data[key])
    }
}

function defineReactive(target, key, val) {
    observe(val)
    Object.defineProperty(target, key, {
        get() {
            console.log(`get ${key}`);
            return val
        },
        set(newValue) {
            console.log(`set ${key}`);
            if(newValue ! == val) { observe(newValue) val = newValue } } }) } observe(data);console.log(data);
Copy the code

The printed result is as follows:It is clear from the figure that there are eight 1’s printed in total, that is to sayobserveIt was executed eight times; So vue2 is recursive to the end to achieve the response. Ok, let’s look at vue3:

  • vue3
function observe(data) {
    console.log(1);
    if (typeofdata ! = ='object' || data == null) {
        return data
    }
    const p = new Proxy(data, {
        get(target, key, receiver) {
            console.log(`get ${key}`)
            const result = Reflect.get(data, key, receiver)
            // Set the response when the value is retrieved
            return observe(result)
        },
        set(target, key, val, receiver) {
            console.log(`set ${key}`)
            const result = Reflect.set(target, key, val, receiver)
            return result
        }
    })
    return p
}

const data = {
    username: 'tom'.profile: {
        city: 'beijing'.a: {
            b: 12.c: {
                d: 23}}}}const p1 = observe(data)
console.log(p1)
Copy the code

The printed result is shown as follows:I only printed a 1 once, which means thatobserveIt’s only done once, and you can see from the code that when you do get in the future,observeIt will be executed again. What does that mean? That is to say,Vue3Deep listening on data is only handled responsively when a value is retrieved, which will definitely improve performance.

controversy

At this point, aside from all the other details, you might say, oh my God, Vue2 can also observe during GET. That’s true, but is there a problem? The problem is that every time you perform a get, you need to perform an observe to retrieve an attribute, and it also traverses down. This adds time complexity. A proxy, on the other hand, will only respond to the level of your get, it won’t do deep traversal. Is that clear?

conclusion

Next, summarize the differences between the two responses

  • Object.defineProperty
    • Deep listening, performance issues
    • Add delete attribute problem, this can refer to an article I wrote in frontSummarize some of Vue’s most commonly used and required apisAnd here it isvue2Why is it neededset&deletetwoapi
    • Array problem, need to rewrite the array prototype several methods
  • Proxy
    • Performance has improved dramatically
    • Solved those problems with VUE2
    • Compatibility to be dealt with

Of course, the sample code is not optimized, in fact, the source code is certainly a variety of cases are also done, here is not to introduce, you can see the source code ha ~ if you have any thoughts about this article or feel wrong, please comment in the comments section! Mutual encouragement for progress ~ ~

reference

Vue2 response formula principle

Vue3 response principle