Vue Mastery

Understanding response

What is reactive? Let’s take a simple example.

let price = 5; let quantity = 2; let total = price * quantity; / / 10Copy the code

Now let’s change the price to 6 and expect the total value to automatically evaluate and update to 12. And this auto-computed update is reactive. In this video we’re going to start by talking about how to trigger a computational update.

How to update the calculation results

let price = 5; let quantity = 2; Let dep = new Set() let effect = () => {total = price * qunatity} function track() Dep.add (effect)} function trigger() {dep.foreach (effect => effect())}Copy the code

As a first step, we need to collect effects so that they can be invoked again when needed.

track()
Copy the code

The second step is to execute effect to obtain the initial result

effect() // total = 10
Copy the code

Third, when the price changes, the collected method is triggered again.

Price = 6 // total = 10 trigger() // total = 12Copy the code

What about multiple attributes?

Above we implemented the storage of a calculation method. In fact, each object will have multiple properties. Each property, in turn, has its own DEP to store one or more effects.

let product = { price: 5, quantity: 2 }
Copy the code

So we set up a big dependency repository: depsMap.

const depsMap = new Map()
Copy the code

In depsMap, the attribute name (such as Price or qunatity) is used as the key and the respective DEP is used as the value. The track method should look like this:

function track(key) { let dep = depsMap.get(key) if (! Depmap.set (key, (dep = new set()))} depmap.add (effect)}Copy the code

Also, the trigger method needs to be rewritten:

function trigger(key) {
  let dep = depsMap.get(key)
  if (dep) {
    dep.forEach(effect => effect())
  }
}
Copy the code

Let’s run it:

let product = { price: 5, quantity: 2 }
let total = 0

let effect = () => { 
  total = product.price * product.quantity
}

track('price')
effect() // total = 10

product.price = 6 // total = 10
trigger('price') // total = 12

Copy the code

What about multiple objects?

Now that we have implemented the response of one object, let’s explore the collection method of multiple objects. We need to create a larger repository to store multiple objects, each with its own depsMap.

Const targetMap = new WeakMap() // Why to use WeakMap we are not going to discuss, just need to know, Function track(target, key) {let depsMap = targetmap. get(target) if (! Set (target, (depsMap = new Map()))} let dep = depsMap. Get (key) if (! dep) { depsMap.set(key, (dep = new Set())) } dep.add(effect) } function trigger(target, key) { const depsMap = targetMap.get(target) if (! Dep = depmap. get(key) if (dep) {dep.foreach (effect => effect())}}Copy the code

Let’s run it:

let product = { price: 5, quantity: 2 }
let total = 0
const depsMap = new Map()
let effect = () => { 
  total = product.price * product.quantity
}

track('product', 'price')
effect() // total = 10

product.price = 6  // total = 10
trigger('product', 'price') // total = 12
Copy the code

conclusion

  • targetMap

Used to store the dependencies of each reactive Object (all properties)

  • depsMap

Used to store a dependency for each attribute of a reactive object

  • dep

Stores all dependencies for an attribute and executes dependencies when the attribute changes