vuehook合集


useBoolean

import { ref } from 'vue';

export const useBoolean = (initValue: boolean = false) => {
  const value = ref(initValue);

  const on = () => {
    value.value = true;
  };
  const off = () => {
    value.value = false;
  };
  const toggle = () => {
    value.value = !value.value;
  };

  return [value, { toggle, on, off }] as const;
};

useInterVal

import { onUnmounted, onUpdated, ref, watchEffect } from 'vue';

type Callback = () => void;

export const useInterVal = (callback: Callback, delaty: number | null) => {
  const savedCallback = ref<Callback>(callback);
  const timer = ref<NodeJS.Timeout | undefined>(undefined);

  onUpdated(() => {
    savedCallback.value = callback;
  });

  watchEffect(() => {
    const tick = () => {
      savedCallback.value();
    };

    if (delaty !== null) {
      timer.value = setInterval(tick, delaty);
    }
  });

  onUnmounted(() => {
    clearInterval(timer.value);
  });
};

useCountDown

import dayjs from 'dayjs';
import { useInfo } from './useInfo';
import { useInterVal } from './useInterVal';

/*
 * 补位
 *
 * param n 数值
 *
 * 时间补位方法
 * 
 */

const bw = (n: number) => {
  return n > 9 ? n : '0' + n;
};

interface CountDown {
  expried: boolean;
  timeStr: string;
  days: number;
  hours: number;
  minutes: number;
  seconds: number;
}

export const useCountDown = (targetTime: string | number | Date) => {
  const { info: timeDiff, setInfoValues: setTimeDiff } = useInfo<CountDown>({
    expried: false,
    timeStr: '',
    days: 0,
    hours: 0,
    minutes: 0,
    seconds: 0,
  });

  const time = () => {
    // 未来时间
    const future = +new Date(targetTime);
    // 现在时间
    const nowDate = +new Date();

    const s = parseInt((future - nowDate) / 1000 + ''); //转化为秒

    // * 天
    const d = parseInt(s / 86400 + '');

    // # 小时
    const h = parseInt((s % 86400) / 3600 + '');

    // todo 分钟
    const ms = parseInt((s % 3600) / 60 + '');

    // ? 秒
    const sc = parseInt((s % 60) + '');

    const expried = s > 0 ? false : true;
    const days = d < 0 ? -d : d;
    const hours = h < 0 ? -h : h;
    const minutes = ms < 0 ? -ms : ms;
    const seconds = sc < 0 ? -sc : sc;

    const isMoreText = expried ? '过去' : '还剩';

    let target = '';
    if (Object.prototype.toString.call(targetTime) === '[object Date]') {
      target = dayjs(targetTime).format('YYYY-MM-DD HH:mm:ss');
    } else {
      target = targetTime as string;
    }
    const timeStr = `距离${target}${isMoreText}:${bw(d)}天-${bw(h)}小时-${bw(ms)}分钟-${bw(sc)}秒`;

    setTimeDiff({
      timeStr,
      expried,
      days,
      hours,
      minutes,
      seconds,
    });
  };

  useInterVal(() => {
    time();
  }, 1000);

  return timeDiff as CountDown;
};

useFuncDebounce

import { ref, onUnmounted } from 'vue';
import _ from 'lodash';

export const useFuncDebounce = function () {
  const timerRef = ref<NodeJS.Timeout | undefined>(undefined);
  /**
   *
   * @param callback 被防抖的函数
   * @param delay 函数延迟执行时间
   * @param change 选择是否改变this指向
   * @returns Function
   */
  function debouncedCallback<T extends Function, K extends unknown, U extends unknown[]>(
    callback: T,
    delay: number = 500,
    change: boolean = true
  ) {
    return function (object?: K, ...args: U) {
      if (timerRef.value) clearTimeout(timerRef.value);
      timerRef.value = setTimeout(function () {
        if (change && _.isObject(object)) {
          callback.apply(object, [object, ...args]);
        } else {
          callback(object, ...args);
        }
      }, delay);
    };
  }

  onUnmounted(() => {
    clearTimeout(timerRef.value);
  });

  return debouncedCallback;
};

useGetList

import { reactive, ref } from 'vue';
import _ from 'lodash';

const ZERO = 0;

const DATALAYERS = 'data.data.records';
const TOTALLAYERS = 'data.data.total';
const MESSAGE = '返回为空!';

interface SetListParamsType<T> {
  res: unknown;
  customFunc?: (list: T) => T;
  path?: string;
}

interface SetTotalParamsType {
  res: unknown;
  path?: string;
}

export const useGetList = <T extends any[]>() => {
  const defaultList: T = [] as unknown as T;

  const data = reactive<T>(defaultList);
  const setData = (list: T) => {
    data.length = 0;
    data.push(...list);
  };

  const total = ref<number>(ZERO);
  const setTotal = (tol: number) => {
    total.value = tol;
  };

  const setDataAuxiliary = ({ res, customFunc, path = DATALAYERS }: SetListParamsType<T>) => {
    if (res) {
      if (customFunc && customFunc instanceof Function) {
        setData(customFunc(_.get(res, path, defaultList)) || defaultList);
      } else {
        setData(_.get(res, path, defaultList) || defaultList);
      }
    } else {
      console.error(MESSAGE);
      setData(defaultList);
    }
  };
  const setTotalAuxiliary = ({ res, path = TOTALLAYERS }: SetTotalParamsType) => {
    if (res) setTotal(_.get(res, path, ZERO) || ZERO);
    else {
      console.error(MESSAGE);
      setTotal(ZERO);
    }
  };

  return [data, setDataAuxiliary, total, setTotalAuxiliary] as const;
};

useInfo

import { onUnmounted, reactive } from 'vue';
import _ from 'lodash';

const INFOLAWERS = 'data.data';

export const useInfo = <T extends Record<string, any>>(initValus = {} as T) => {
  const info = reactive(initValus) as Record<string, any>;

  const setSyncInfo = (res: unknown, path = INFOLAWERS) => {
    try {
      const data = _.get(res, path);
      for (const key in data) {
        info[key] = data[key];
      }
    } catch (error) {
      console.log('setSyncInfo error', error);
    }
  };
  const setInfoValues = (object: any) => {
    for (const key in object) {
      info[key] = object[key];
    }
  };
  const setInfoValue = (key: string, value: any) => {
    info[key] = value;
  };

  const clear = () => {
    for (const key in info) {
      info[key] = '';
    }
  };

  onUnmounted(() => {
    clear();
  });

  return { info, clear, setSyncInfo, setInfoValues, setInfoValue } as const;
};

useMountRef

import { onMounted, onUnmounted, ref } from 'vue';

export const useMountRef = () => {
  const mountedRef = ref<boolean>(false);
  onMounted(() => {
    mountedRef.value = true;
  });
  onUnmounted(() => {
    mountedRef.value = false;
  });

  return mountedRef;
};

useOffsetTop

import { onMounted, onUnmounted, ref } from 'vue';

interface OffsetProps {
  extraHeight?: number;
  id?: string;
}

interface DomAttr {
  top: number;
  bottom: number;
  height: number;
  left: number;
  right: number;
  width: number;
  x: number;
  y: number;
}

const BODYELEMENT = 'body';
const body = document.getElementsByTagName(BODYELEMENT)[0];

/**
 *
 * @param extraHeight 预留高度部分
 * @param id id
 * @returns
 */
export const useOffsetTop = ({ extraHeight = 80, id }: OffsetProps = {}) => {
  const tableRef = ref<HTMLDivElement | null>(null);

  const height = ref<number>(0);
  const setHeight = (h: number) => {
    height.value = h;
    return height.value;
  };

  const getOffsetTop = () => {
    if (tableRef.value && tableRef.value instanceof HTMLDivElement) {
      const { top } = tableRef.value?.getBoundingClientRect() as DomAttr;
      id ? tableRef.value.setAttribute('data-key', id) : null;
      const tableHeight = document.body.clientHeight - top - extraHeight;
      return tableHeight;
    }

    return 0;
  };

  const saveHeightChange = () => {
    const height = getOffsetTop() >= 0 ? getOffsetTop() : 0;
    return setHeight(height);
  };

  const resizeObserver = new ResizeObserver(function (entry) {
    saveHeightChange();
  });

  onMounted(() => {
    resizeObserver.observe(body);
  });
  onUnmounted(() => {
    saveHeightChange(), resizeObserver.disconnect();
  });

  return [tableRef, height] as const;
};

useThrottle

import { onUnmounted, ref } from 'vue';

export const useThrottle = () => {
  const valid = ref<boolean>(false);
  const timer = ref<NodeJS.Timeout | undefined>(undefined);

  const throttleCallback = (fn: Function, delay: number = 500) => {
    return (config?: unknown, ...args: unknown[]) => {
      if (valid.value) return;

      valid.value = true;
      timer.value = setTimeout(() => {
        valid.value = false;
        fn.apply(config, [config, ...args]);
      }, delay);
    };
  };

  onUnmounted(() => {
    clearTimeout(timer.value);
  });

  return throttleCallback;
};

useRequest

见前一篇文章

文章作者: KarlFranz
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 reprint policy. If reproduced, please indicate source KarlFranz !
评论
  目录