watch.ts 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. import { watchEffect, nextTick, effectScope } from "vue";
  2. import { diffArrayChange } from './diff'
  3. import type { EffectScope } from 'vue'
  4. // 一次监听
  5. export const onlyWatchEffect: typeof watchEffect = (cb, options) => {
  6. const stopWatch = watchEffect((...args) => {
  7. cb(...args);
  8. nextTick(stopWatch);
  9. }, options);
  10. return stopWatch;
  11. };
  12. export const shallowWatchArray = <T extends any[]>(
  13. getItems: () => T,
  14. cb: (newItems: T, oldItems: T) => void
  15. ) => {
  16. let oldItems = [] as unknown as T
  17. watchEffect(() => {
  18. const newItems = getItems()
  19. cb(newItems, oldItems)
  20. oldItems = [...newItems] as T
  21. })
  22. }
  23. export const arrayChildEffectScope = <T extends any[]>(
  24. getItems: () => T,
  25. cb: (item: T[number]) => void
  26. ) => {
  27. const scopes = new WeakMap<T, EffectScope>()
  28. shallowWatchArray(getItems, (newItems, oldItems) => {
  29. const { added, deleted } = diffArrayChange(newItems, oldItems)
  30. for (const addItem of added) {
  31. const scope = effectScope()
  32. scope.run(() => {
  33. cb(addItem)
  34. })
  35. scopes.set(addItem, scope)
  36. }
  37. for (const delItem of deleted) {
  38. scopes.get(delItem)?.stop()
  39. }
  40. })
  41. }