useWindowSize.ts 1.2 KB
Newer Older
陈文彬 已提交
1 2 3 4 5 6
import type { Fn } from './types';

import { tryOnMounted, tryOnUnmounted } from '/@/utils/helper/vueHelper';
import { ref } from 'vue';

import { useDebounce } from '/@/hooks/core/useDebounce';
V
vben 已提交
7
import { CancelFn } from '../core/types';
陈文彬 已提交
8 9 10 11 12 13 14

interface WindowSizeOptions {
  once?: boolean;
  immediate?: boolean;
  listenerOptions?: AddEventListenerOptions | boolean;
}

V
vben 已提交
15
export function useWindowSizeFn<T>(fn: Fn<T>, wait = 150, options?: WindowSizeOptions): CancelFn {
陈文彬 已提交
16 17 18 19 20 21 22
  let handler = () => {
    fn();
  };
  const [handleSize, cancel] = useDebounce(handler, wait, options);
  handler = handleSize;

  tryOnMounted(() => {
V
vben 已提交
23 24 25
    if (options && options.immediate) {
      handler();
    }
陈文彬 已提交
26 27
    window.addEventListener('resize', handler);
  });
V
vben 已提交
28

陈文彬 已提交
29 30 31 32
  tryOnUnmounted(() => {
    window.removeEventListener('resize', handler);
    cancel();
  });
V
vben 已提交
33
  return cancel;
陈文彬 已提交
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
}

export const useWindowSize = (wait = 150, options?: WindowSizeOptions) => {
  const widthRef = ref(0);
  const heightRef = ref(0);

  function setSize() {
    widthRef.value = window.innerWidth;
    heightRef.value = window.innerHeight;
  }
  setSize();

  const handler = () => {
    setSize();
  };

  useWindowSizeFn(handler, wait, options);

  return { widthRef: widthRef, heightRef: heightRef };
};