vue3 hook库

import { ElNotification } from "element-plus";
/**
 * @description 接收数据流生成 blob,创建链接,下载文件
 * @param {any} data 导出的文件blob数据 (必传)
 * @param {String} tempName 导出的文件名 (必传)
 * @param {Boolean} isNotify 是否有导出消息提示 (默认为 true)
 * @param {String} fileType 导出的文件格式 (默认为.xlsx)
 * */
interface useDownloadParam {
  data: any;
  tempName: string;
  isNotify?: boolean;
  fileType?: string;
}

export const useDownload = async ({ data, tempName,isNotify = true, fileType = ".xlsx" }: useDownloadParam) => {
  if (isNotify) {
    ElNotification({
      title: "温馨提示",
      message: "如果数据庞大会导致下载缓慢哦,请您耐心等待!",
      type: "info",
      duration: 3000
    });
  }
  try {
    const blob = new Blob([data]);
    // 兼容 edge 不支持 createObjectURL 方法
    if ("msSaveOrOpenBlob" in navigator) return window.navigator.msSaveOrOpenBlob(blob, tempName + fileType);
    const blobUrl = window.URL.createObjectURL(blob);
    const exportFile = document.createElement("a");
    exportFile.style.display = "none";
    exportFile.download = `${tempName}${fileType}`;
    exportFile.href = blobUrl;
    document.body.appendChild(exportFile);
    exportFile.click();
    // 去除下载对 url 的影响
    document.body.removeChild(exportFile);
    window.URL.revokeObjectURL(blobUrl);
  } catch (error) {
    console.log(error);
  }
};

import { cloneDeep } from 'lodash-es'

export default function useCustomReactive<T extends object>(obj: T) {
  const initState = cloneDeep(obj)
  const state = reactive<T>(obj)

  function reset() {
    for (const key in state) {
      state[key] = initState[key as string]
    }
  }

  return { state, reset }
}

export default function useDisableLabelForSwitch() {
  onMounted(() => {
    nextTick(() => {
      const arr = document.querySelectorAll('.el-switch input')
      arr.forEach(el => {
        console.log('禁用switch label for关联')
        el?.removeAttribute('id')
      })
    })
  })
}

import { onMounted, type Ref, ref } from 'vue'

interface HookOptions<P = any, D = any> {
  /**
   * 是否自动请求,为true时,将在onMounted钩子自动执行一次getData
   */
  auto?: boolean

  loading?: Ref<boolean>

  params?: P

  success?: (res: D | undefined) => void
}

/**
 * 默认参数
 */
const defaultOptions: HookOptions = {
  auto: false
}

type FunctionParams<T> = T extends (arg: infer P) => any ? P : never

type ApiResult<T extends PromiseFn> = PromiseValue<ReturnType<T>>

export default function useRequest<
  API extends PromiseFn,
  D extends FunctionParams<API>
>(api: API, options?: HookOptions<D, ApiResult<API>>) {
  options = { ...defaultOptions, ...options }

  const loading = ref(false)
  const data = ref<PromiseValue<ReturnType<API>>>()

  // 切换loading状态
  function toggleLoading(flag: boolean) {
    loading.value = flag
    // 如果设置了自定义loading属性,则一起切换
    if (options?.loading !== undefined) {
      options.loading.value = flag
    }
  }

  // 获取数据
  async function request(
    params?: Partial<FunctionParams<API>>
  ): Promise<PromiseValue<ReturnType<API>>> {
    toggleLoading(true)
    try {
      const res = await api({
        ...options?.params,
        ...params
      })
      if (options?.success) {
        options.success(res)
      }
      data.value = res
      return res
    } catch (err) {
      throw err
    } finally {
      toggleLoading(false)
    }
  }

  onMounted(() => {
    if (options?.auto) {
      request()
    }
  })

  return {
    loading,
    data,
    request
  }
}

你可能感兴趣的:(vue.js,javascript,前端)