美文网首页
Vue 中的响应性是如何工作的

Vue 中的响应性是如何工作的

作者: 如果俞天阳会飞 | 来源:发表于2022-08-11 10:25 被阅读0次

根据官网代码介绍实现 类似 watchEffect功能

<script lang="ts" setup>

let count = {
  a1: 1,
  a2: 2
};

let total = 0;

let activeEffect: any = null;

const WeakMap = new Map<string, any>();

const reactive = (object: object) => {
  return new Proxy(object, {
    get(target: object, key: string, receiver: any): any {
      track(target, key);
      return target[key]
    },
    set(target: object, key: string, value: any, receiver: any): boolean {
      target[key] = value;
      trigger(target, key);
      return true
    }
  })
};

const getSubscribersForProperty = (target: object, key: string) => {
  if (!WeakMap.get(key)) {
    const row = new Set();
    WeakMap.set(key, row)
  }
  return WeakMap.get(key)
};

const track = (target: any, key: string) => {
  if (activeEffect) {
    // 副作用订阅将被存储在一个全局的 WeakMap<target, Map<key, Set<effect>>> 数据结构中
    const effects = getSubscribersForProperty(target, key);
    if (effects) {
      effects.add(activeEffect)
    }
  }
};

const trigger = (target: any, key: string) => {
  const effects = getSubscribersForProperty(target, key);
  effects?.forEach((effect: any) => {
    effect()
  })
};

const customWatch = (update: Function) => {
  const effect = () => {
    activeEffect = effect;
    update();
    activeEffect = null;
  };
  effect();
};

// demo

const reactiveCount = reactive(count);

customWatch(() => {
  total = reactiveCount.a1 + reactiveCount.a2;
  console.log(total);
});

setTimeout(() => {
  // 任意依赖被改动时重新运行 customWatch 打印为 6
  reactiveCount.a1 = 4;
}, 1000);

setTimeout(() => {
  // 任意依赖被改动时重新运行 customWatch 打印为 8
  reactiveCount.a2 = 4;
}, 2000);
</script>

相关文章

网友评论

      本文标题:Vue 中的响应性是如何工作的

      本文链接:https://www.haomeiwen.com/subject/ovyxgrtx.html