An overview of the
The Vue source section talks about dependency collection and triggering is more complex and not easy to understand. And today I’m going to do it in the simplest way possible. If you have a harvest, please give my little brother a thumbs-up.
preparation
- Declare a Map for saving;
- Current is used to pass data;
- Data backup;
const map = new Map(a);let current = null;
const data = {
name: 'madapao'.age: 18.sex: 'male',}Copy the code
Create a Watcher class
The DEPS array collects dependencies, and the add method adds dependencies.
class Watcher {
constructor() {
this.deps = [];
}
add(dep) {
this.deps.push(dep)
}
}
Copy the code
Collection and triggering
Hijacking of data in data:
- Get: Check if there is a key in the map. If not, create a new Watcher and add current to the dePS of the watcher. Each key corresponds to a Watcher in the map. If you already have one, just pull out wathcer and add current to Watcher’s DEPS.
- Set: Take the watcher corresponding to the key in the map and execute all the methods in its deps once.
Object.keys(data).forEach(key= > {
Object.defineProperty(data, key, {
get() {
if (map.has(key)) {
const watcher = map.get(key);
watcher.add(current);
map.set(key, watcher)
} else {
const watcher = newWatcher(); watcher.add(current); deps.set(key, watcher); }},set() {
if (map.has(key)) {
map.get(key).deps.forEach(fn= > fn())
}
}
})
})
Copy the code
use
Execute getAgeName, temporarily assign getAgeName to current, and use data key in data. It triggers the get of the key. Put getAgeName into the dePS for watcher.
When you change the value of a key, it triggers all the methods watcher has collected for the key.
function getAgeName() {
current = getAgeName;
console.log('getAgeName executed ')
return `${data.name}'this year'${data.age}Years old. `
}
function getSexName() {
current = getSexName;
console.log('getSexName executed ')
return `${data.name}'Is a'${data.sex}People. `
}
getAgeName();
getSexName();
data.name = 'mahaha';
Copy the code
All the code
const deps = new Map(a);let current = null;
class Watcher {
constructor() {
this.deps = [];
}
add(dep) {
this.deps.push(dep)
}
}
const data = {
name: 'madapao'.age: 18.sex: 'male',}Object.keys(data).forEach(key= > {
Object.defineProperty(data, key, {
get() {
if (deps.has(key)) {
const watcher = deps.get(key);
watcher.add(current);
deps.set(key, watcher)
} else {
const watcher = newWatcher(); watcher.add(current); deps.set(key, watcher); }},set() {
if (deps.has(key)) {
deps.get(key).deps.forEach(fn= > fn())
}
}
})
})
function getAgeName() {
current = getAgeName;
console.log('getAgeName executed ')
return `${data.name}'this year'${data.age}Years old. `
}
function getSexName() {
current = getSexName;
console.log('getSexName executed ')
return `${data.name}'Is a'${data.sex}People. `
}
getAgeName();
getSexName();
data.name = 'mahaha';
Copy the code