origin

After looking at vue3’s Reactivity module, a million ideas came into my head.

I had to write an essay to record what was in my head

I’m afraid my brain will explode if I think too much

First of all, most of the discussions on various forums are direct analysis of vuE3 source code

But I think it’s better to analyze the process than to analyze the source code directly

How was it designed, the thought process that was the most fascinating

The result is just a product of this thinking

When you have the idea in your head

It drives me to understand and explore how reactivity is designed

So I wanted to describe the whole process of thinking about design based on my own understanding

The beginning of thinking

So let’s start thinking about it from zero

First, every technology is driven by a need or a problem

So let’s start with the simplest question

Look at the code


const data = {
    name:"cxr"
}

const myTitle = ""
function update () {
    myTitle = data.name + "Title"
}

update()
console.log(myTitle) // cxrTitle
data.name = "kkb"
update()
console.log(myTitle) // kkbTitle

Copy the code

First we have a variable myTitle

It then relies on data.name

When our data.name changes

If we want the value of myTitle variable to change as well

We have to call update manually

Otherwise our myTitle wouldn’t be able to update

Of course, this is just a simple example, but more often than not we update the data and then need to update the UI

This is how people were programming in the era of jquery

Then we need to think about it.

Is it possible that when we change data.name, all views or functions that depend on it will be executed automatically? Just like we did when we called update manually.

Ok, so this is where you start thinking about responsive programming.

But what to call it? What does it matter if it’s ha-ha-ha or hey, hey, hey, hey?

Finally, let’s take stock of our requirements

When a data is changed, all functions that depend on that data are automatically executed

When a data is changed, all functions that depend on that data are automatically executed

So how do you implement this requirement?

Let’s reason things out

First we need to know which functions depend on this data

And then we need to collect all of these functions

We can call these collected functions manually when we change the data

Just to sort out our problem points a little bit

  1. Dependencies on the current data need to be collected
    1. How and where?
    2. How do I get this dependency function?
  2. The collected dependency functions are called when data is changed
    1. How do you know if the data has changed?
    2. How do I get the previously collected dependency functions?

The first problem I found to be solved was 1.2

Only after we get the dependency function first can we solve the following problems

This question is a start

const data = {
    name:"cxr"
}

let myTitle = ""

function update () {
    myTitle = data.name + "Title"
}

// Rely on collection
const dependCollection = {}
dependCollection.data = {};
dependCollection.data.name = [];
dependCollection.data.name.push(update)
Copy the code

Hahaha, I did it in the lowest way possible

Where is Low? Low is hard coded now

But it doesn’t matter it doesn’t matter for now is enough to solve our problem

Ps: I was too clever to do this dependency collection in just a few seconds hahaha

Now consider another question: how do we trigger our collected dependency functions when changing data?

There is an answer to that question

Before vuE3 we used Object.defineProperty

Now let’s use a proxy

// Trigger dependencies
const handler = {
  get: function (obj, prop) {
    return Reflect.get(obj, prop);
  },
  set: function (obj, prop, value) {
    const result = Reflect.set(obj, prop, value);
    // Trigger functions that depend on the current data
    dependCollection.data.name.forEach((fn) = > fn());
    return result
  },
};

const observed = new Proxy(data, handler);
observed.name = "kkb"
console.log(myTitle)
Copy the code

After using proxy, we can know when to update the data

Once we know this node, wouldn’t it be good to trigger dependencies after the data is updated

I tried it very simply

Sure enough, when we updated the observed. Name

MyTitle updates itself hahaha

There is nothing wrong with old iron

The effect was achieved

But our current code is so low, it’s hard coded

So how do we write a more general logic for collecting and triggering dependencies

Ps: proxy: MDN

Write more general dependency collection and triggering dependency functions

TODO

Tired tired, tomorrow to continue to think