Vue3.0 was released by the official Vue team on September 18, 2020 at around 11:30 PM 🎉. Code-named One Piece.

Vue 3.0 has finally been released. See v3.0.0 for details. Official website address Vue, but the content is still in English, after all, just released, Chinese content is not so fast.

Vue3 English Guide

Instead, read the repository documentation for yourself and see what changes Vue3 brings to the table.

Original address: github.com/vuejs/docs-…

Deep into the responsivity principle

Now it’s time to dig deeper! One of the most unique features of Vue is its non-invasive responsive system. The data model is simply a proxied JavaScript object. And when you modify them, the view is updated. This makes state management very straightforward, but it’s also important to understand how it works so you can avoid some common problems. In this chapter, we’ll look at the low-level details of Vue responsive systems.

Watch the free in-depth responsive videos on Vue Mastery. If not, click on the link below

Vue Mastery watch in-depth responsive Principles videos

What is reactive

This term is being used a lot in programming these days, but what do people mean when they say it? Reactive is a programming paradigm that allows us to adjust changes declaratively. The typical example that people usually show, and it’s a good one, is an Excel spreadsheet.

Excel spreadsheet demo video

If you put the number 2 in the first cell and the number 3 in the second cell and SUM it, the spreadsheet will calculate it for you. This is no surprise. But if you update the first number, the SUM automatically updates the SUM as well.

JavaScript usually doesn’t work like this — if we want to write something like this in JavaScript:

var val1 = 2
var val2 = 3
var sum = val1 + val2

// sum
/ / 5

val1 = 3

// sum
/ / 5
Copy the code

If we update the first value, sum doesn’t change.

So how do we do this in JavaScript?

  • Detect when one of these values changes
  • Modify it with the track function
  • Update to the latest value with the trigger function

How does Vue track change?

When a normal JavaScript object is passed to an application or component instance as a data option, Vue iterates through all of its properties and converts it to a Proxy using handlers with getters and setters. This is the only feature in ES6, but we have versions of IE supported in Vue 3 that use the older technology Object.defineProperty. Both expose the same API, but the Proxy version is more streamlined and improves performance.

See the Pen <a href=’https://codepen.io/sdras/pen/zYYzjBg’>Proxies and Vue’s Reactivity Explained Visually</a> by Sarah Drasner (<a href=’https://codepen.io/sdras’>@sdras</a>) on <a href=’https://codepen.io’>CodePen</a>.

This part urgently needs to master part of the Proxy knowledge to help understand! So, let’s take a closer look. There is a lot of literature on proxies, but what you really need to know is that a Proxy is an object that wraps around another object or function and allows you to intercept it.

We use it like this: New Proxy(target, handler)

const dinner = {
  meal: 'tacos'
}

const handler = {
  get(target, prop) {
    return target[prop]
  }
}

const proxy = new Proxy(dinner, handler)
console.log(proxy.meal)

// tacos
Copy the code

Okay, so far, we’ve just wrapped this object and returned it. It’s cool, but it doesn’t work. Note, however, that we can intercept objects while wrapping them in proxies. This interception is called a catcher.

const dinner = {
  meal: 'tacos'
}

const handler = {
  get(target, prop) {
    console.log (' intercepted! ')return target[prop]
  }
}

const proxy = new Proxy(dinner, handler)
console.log(proxy.meal)

// intercepted!
// tacos
Copy the code

Except for console logs, we can do anything we want here. We may not even return the actual value if we wish. This is why proxies are so powerful at creating apis.

In addition, Proxy provides another feature. Instead of returning a value like: target[prop], we can go further and use a method called Reflect, which allows us to correctly perform this binding, like this:

const dinner = { meal: 'tacos' } const handler = { get(target, prop, receiver) { return Reflect.get(... arguments) } } const proxy = new Proxy(dinner, handler) console.log(proxy.meal) // intercepted! // tacosCopy the code

As we mentioned earlier, in order to have an API that updates the final value when something changes, we have to set the new value when something changes. We do this in a processor function called track, which takes in the target and key arguments.

const dinner = { meal: 'tacos' } const handler = { get(target, prop, receiver) { track(target, prop) return Reflect.get(... arguments) } } const proxy = new Proxy(dinner, handler) console.log(proxy.meal) // intercepted! // tacosCopy the code

Finally, we set new values when something changes. To do this, we will set these updates in the new proxy via trigger changes:

const dinner = {
  meal: 'tacos'
}

const handler = {
  get(target, prop, receiver) {
    track(target, prop)
    return Reflect.get(... arguments) },set(target, key, value, receiver) {
    trigger(target, key)
    return Reflect.set(... arguments) } }const proxy = new Proxy(dinner, handler)
console.log(proxy.meal)

// intercepted!
// tacos
Copy the code

Remember the list of the first few paragraphs? Now we have some answers on how to handle these changes with Vue:


  • Detect when a value has changed
    : We no longer need to do this because the Proxy allows us to intercept it
  • Trace the function that changes it: We perform this operation in the getter in Proxy, calledeffect
  • Fire the function so that it can update the final value: We do this in the setter in Proxy namedtrigger

Proxy objects are invisible to the user, but internally, they enable Vue to do dependency tracking and change notification in the event that the value of a property is accessed or modified. Starting with Vue 3, we can use reactive in separate packages. One thing to note is that when converted data objects are printed in browser control desktop formats are different, so you may need to install Vue-DevTools to provide a more user-friendly visual interface.

The Proxy object

Vue internally keeps track of all objects that have been set up to be reactive, so it always returns a Proxy version of the same object.

When a nested object is accessed from a reactive Proxy, the object is also converted to Proxy before returning:

const handler = {
  get(target, prop, receiver) {
    track(target, prop)
    const value = Reflect.get(... arguments)if (isObject(value)) {
      return reactive(value)
    } else {
      return value
    }
  }
  // ...
}
Copy the code

Proxy VS Original id

The use of Proxy does introduce a new warning that needs to be noted: the proxied object is not equal to the original object under the congruent comparator (===). Such as:

const obj = {}
const wrapped = new Proxy(obj, handlers)

console.log(obj === wrapped) // false
Copy the code

In most cases, the original and wrapped versions behave the same, but note that they will differ under operations that rely on strict comparisons, such as.filter() or.map(). These warnings are less likely to occur when using the options API because all reactive states are accessed through this and guaranteed to have been proxyed.

However, when creating reactive objects explicitly using the composition API, it is best practice not to keep references to native objects and only operate on reactive versions:

const obj = reactive({
  count: 0
}) // Do not reference the original object
Copy the code

Listener (observer)

Each component instance has a corresponding listener instance, which records any properties “touched” during the component rendering process as dependencies. Later, when the setter for the dependency fires, it notifies the listener, causing the component to re-render.

See the Pen <a href=’https://codepen.io/sdras/pen/GRJZddR’>Second Reactivity with Proxies in Vue 3 Explainer</a> by Sarah Drasner (<a href=’https://codepen.io/sdras’>@sdras</a>) on <a href=’https://codepen.io’>CodePen</a>.

When you pass an object as data to a component instance, Vue converts it into a Proxy. This Proxy enables Vue to perform dependency tracking and change notification when a property is accessed or modified. Each property is treated as a dependency.

After the first rendering, the component keeps track of a list of dependencies — properties that were accessed during rendering. The component, in turn, becomes a subscriber to each of its properties. When the Proxy intercepts the set operation, the property notifies all of its subscribed components to rerender.

If you are using vue 2.x and below, you may be interested in some of the change detection warnings that exist in these versions, here are some more details worth exploring.