Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[js] vue 响应式原理 #27

Open
meooxx opened this issue Mar 8, 2021 · 0 comments
Open

[js] vue 响应式原理 #27

meooxx opened this issue Mar 8, 2021 · 0 comments

Comments

@meooxx
Copy link
Owner

meooxx commented Mar 8, 2021

let activeUpdate = '';
class Dep {
  constructor() {
    this.subcriber = new Set();
  }

  depend() {
    if (!activeUpdate) return;
    this.subcriber.add(activeUpdate);
  }

  notify() {
    this.subcriber.forEach((f) => f());
  }
}
const dep = new Dep();
function observe(data) {
  Object.keys(data).forEach((key) => {
    // good
    let v = data[key];
    // bad
    // return data[key] 爆栈
    Object.defineProperty(data, key, {
      get() {
        // 3 收集依赖,因为在update内执行,所以可以获取到update执行时候设置的activeUpdate
        dep.depend();
        return v;
      },
      set(newv) {
        if (newv === v) return;
        v = newv;
        // 5 遍历Dep类中由depend收集的依赖回调执行
        dep.notify();
      },
    });
  });
}

function autoRun(update) {
  const wrapUpdate = () => {
    activeUpdate = wrapUpdate;
    update();
    activeUpdate = null;
  };
  wrapUpdate();
}
const data = {
  count: 1,
};

// 0 转换data,提供get,set属性
observe(data);
// 1 执行updatedata
autoRun(() => {
// 2 访问get属性
  console.log('count:', data.count);
});
autoRun(() => {
  // good
  console.log(data.count + 1);
  // bad
  // console.log(data.count++)
  // data.count++ 触犯autoRun, autoRun data.count++ -> 触发autoRun
});

data.count++;
data.count++;
data.count++;

0 将data转换为响应式的
1 运行autoRun, autoRun将执行回调函数update的方法挂到全局(wrappedUpdate) activeUpdate上面
2 执行update, 此时如果函数有读取操作即访问了get属性, 则触发definePropertor 中的 depend
3 depend在update执行中执行, 可以读取到全局的activeUpdate,此时可以将update置入依赖回调收集set中
4 update执行完毕后,将当前activeUpdate置为null
5 更改值, 触发set触发notify, 遍历收集的依赖执行

参考:amandakelake/blog#63

@meooxx meooxx changed the title [js] vue 响应式 [js] vue 响应式原理 Mar 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant