useHeights.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import { onUnmounted, watch, ref } from 'vue';
  2. import wrapperRaf from '../../_util/raf';
  3. export default function useHeights(mergedData, getKey, onItemAdd, onItemRemove) {
  4. const instance = new Map();
  5. const heights = new Map();
  6. const updatedMark = ref(Symbol('update'));
  7. watch(mergedData, () => {
  8. updatedMark.value = Symbol('update');
  9. });
  10. let collectRaf = undefined;
  11. function cancelRaf() {
  12. wrapperRaf.cancel(collectRaf);
  13. }
  14. function collectHeight() {
  15. cancelRaf();
  16. collectRaf = wrapperRaf(() => {
  17. instance.forEach((element, key) => {
  18. if (element && element.offsetParent) {
  19. const {
  20. offsetHeight
  21. } = element;
  22. if (heights.get(key) !== offsetHeight) {
  23. //changed = true;
  24. updatedMark.value = Symbol('update');
  25. heights.set(key, element.offsetHeight);
  26. }
  27. }
  28. });
  29. });
  30. }
  31. function setInstance(item, ins) {
  32. const key = getKey(item);
  33. const origin = instance.get(key);
  34. if (ins) {
  35. instance.set(key, ins.$el || ins);
  36. collectHeight();
  37. } else {
  38. instance.delete(key);
  39. }
  40. // Instance changed
  41. if (!origin !== !ins) {
  42. if (ins) {
  43. onItemAdd === null || onItemAdd === void 0 ? void 0 : onItemAdd(item);
  44. } else {
  45. onItemRemove === null || onItemRemove === void 0 ? void 0 : onItemRemove(item);
  46. }
  47. }
  48. }
  49. onUnmounted(() => {
  50. cancelRaf();
  51. });
  52. return [setInstance, collectHeight, heights, updatedMark];
  53. }