更新记录

1.0.1(2025-07-14) 下载此版本

首次发布


平台兼容性

uni-app(4.45)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 快应用-华为 快应用-联盟

useRequest Hook(uniapp vue3)

一个功能强大且高度可配置的 Vue 3 Composition API 请求 Hook,灵感来源于 ahooksSWR。它内置了缓存、防抖、节流、轮询、重试、请求队列和并发控制等特性。

注意:如您下载使用本插件,请注意导入路径

特性

  • 🚀 开箱即用:仅需一个 URL 即可发起请求。
  • TypeScript 支持:提供完整的类型定义,保障代码健壮性。
  • 🔄 自动请求与手动控制:支持组件挂载时自动请求,也支持手动触发。
  • 🧠 状态管理:自动管理 loading, data, error 等响应式状态。
  • 💾 缓存:内置请求缓存,可自定义缓存时间,避免重复请求。
  • 防抖 & 节流:轻松处理高频触发的请求场景。
  • polling 轮询:支持轮询,可手动开始或停止。
  • 🔗 依赖请求:支持根据响应式状态的变化来决定是否发起请求。
  • ♻️ 错误重试:内置请求失败后的重试机制。
  • 🎏 拦截器:支持请求、响应和错误拦截器,轻松实现全局逻辑处理(如 Token 添加、统一错误上报等)。
  • 🔌 插件化:核心逻辑可通过插件扩展。
  • 🛑 请求取消:可以取消正在进行的请求。
  • 🚦 请求队列与并发控制:管理请求的执行顺序和并发数量。

快速上手

1. 全局配置与拦截器 (在 App.vue 中)

这是使用 useRequest 的第一步,也是最重要的一步。在应用的入口处(通常是 App.vue)进行全局配置。

// App.vue
import {
  setConfig,
  setBaseURL,
  addInterceptor,
  createRequestInterceptor,
  createResponseInterceptor,
  createErrorInterceptor,
} from "uniapp-use-request";

// 1. 设置全局基础 URL
setBaseURL("https://api.example.com");

// 2. 设置全局默认配置
setConfig({
  timeout: 15000,
  showLoading: true, // 默认显示 uni.showLoading
  loadingText: "加载中...",
  showError: true, // 默认显示 uni.showToast
  retryCount: 1, // 失败后默认重试1次
});

// 3. 添加请求拦截器
addInterceptor(
  createRequestInterceptor((config) => {
    console.log("[useRequest] 请求拦截器: ", config);
    // 自动添加 Token
    if (config.withToken) {
      const token = uni.getStorageSync("token");
      if (token) {
        config.headers = {
          ...config.headers,
          Authorization: `Bearer ${token}`,
        };
      }
    }
    return config;
  })
);

// 4. 添加响应拦截器
addInterceptor(
  createResponseInterceptor((response, config) => {
    console.log("[useRequest] 响应拦截器: ", response);
    // 这里可以对响应数据进行统一处理
    // 例如,根据后端的业务码判断请求是否成功
    const res = response as any;
    if (res.code !== 200) {
      // 抛出错误,会进入错误拦截器
      throw new Error(res.message || "业务请求失败");
    }
    // 只返回 data 字段
    return res.data;
  })
);

// 5. 添加错误拦截器
addInterceptor(
  createErrorInterceptor((error, config) => {
    console.error("[useRequest] 错误拦截器: ", error);
    // 这里可以对错误进行统一处理,例如上报错误日志、弹窗提示等
    if (config.showError) {
      uni.showToast({
        title: error.message || "请求异常",
        icon: "none",
      });
    }
    // 返回错误对象,如果想在业务代码中继续处理错误
    return error;
  })
);

2. 在页面或组件中使用

默认自动请求

useRequest 默认在组件挂载后自动发起请求。

// pages/some-page/index.vue
import { useRequest } from "uniapp-use-request";
import { watch } from "vue";

const { data, loading, error } = useRequest<User>("/api/user/profile");

watch(data, (newData) => {
  if (newData) {
    console.log("获取到用户信息:", newData);
  }
});

import { useRequest } from "uniapp-use-request";
const { data, loading, error } = useRequest("technew/index/indexConfig",{
    params: {
        type: "login",
    },
    method: "POST",
});

手动触发请求

设置 manual: true,请求将不会自动发起,需要手动调用 run 方法。

const { loading, run: login } = useRequest("/api/login", {
  manual: true,
  method: "POST",
});

const handleLogin = async () => {
  try {
    const result = await login({ username: "test", password: "123" });
    console.log("登录成功:", result);
  } catch (e) {
    console.error("登录失败:", e);
  }
};

高级用法

缓存

设置 cacheTime,在指定时间内,同样的请求将直接返回缓存数据。

const { data, loading } = useRequest("/api/articles", {
  cacheTime: 5 * 60 * 1000, // 缓存5分钟
});

// 手动清除该请求的缓存
const { clearCache } = useRequest("/api/articles");
clearCache();

防抖与节流

适用于搜索等高频触发场景。

// 防抖:输入停止后 500ms 才发起请求
const { run: search } = useRequest("/api/search", {
  manual: true,
  debounce: true,
  debounceTime: 500,
});

search();

// 节流:每 500ms 最多发起一次请求
const { run: submit } = useRequest("/api/submit", {
  manual: true,
  throttle: true,
  throttleTime: 500,
});

submit();

轮询

通过 pollingInterval 设置轮询间隔。

const { data, polling, startPolling, stopPolling } = useRequest("/api/status", {
  pollingInterval: 3000, // 每3秒轮询一次
  pollingMaxCount: 10, // 最多轮询10次
});

// 手动停止
stopPolling();
// 手动开始
startPolling();

请求依赖 (ready)

ready 的值为 true 时,请求才会发起。ready 可以是一个 ref

import { ref, computed } from "vue";

const userId = ref("");

const { data } = useRequest("/api/user/detail", {
  // 使用 computed 确保 ready 是响应式的
  ready: computed(() => !!userId.value),
  params: {
    id: userId, // useRequest 会自动解包 ref
  },
});

// 在获取到 userId 后,请求会自动发出
userId.value = "user-123";

请求取消

可以手动取消一个正在进行的请求。

const { run, cancel, loading } = useRequest("/api/long-request", {
  manual: true,
});

run();

// 3秒后如果请求还未完成,则取消它
setTimeout(() => {
  if (loading.value) {
    cancel();
  }
}, 3000);

请求队列与并发控制


// 请求2: 获取提现列表 (高优先级)
const { data: userInfo, run } = useRequest("technew/my.Index/withdrawList", {
    manual: true,
    requestId: "user-init",
    priority: 10, // 高优先级
    method: "POST",
});
// 请求1: 获取登录配置 (低优先级)
const { data: loginConfig, run: getConfig } = useRequest("technew/index/indexConfig", {
    manual: true,
    requestId: "user-init",
    priority: 1, // 低优先级
    params: { type: "login" },
});

// 同时触发两个请求,它们将根据优先级排队执行
getConfig();
run();

API 参考

useRequest 参数

参数 说明 类型 默认值
url 请求地址或请求函数 string \| ((params?: any) => string) -
options 请求配置 RequestOptions {}

RequestOptions (部分常用)

参数 说明 类型 默认值
manual 是否手动触发 boolean false
params 请求参数,会自动拼接到 URL 或作为 data Record<string, any> {}
data 请求体数据 any -
method 请求方法 GET POST GET
cacheTime 缓存时间(ms),0 表示不缓存 number 0
retryCount 失败后重试次数 number 0
debounce 是否开启防抖 boolean false
debounceTime 防抖时间(ms) number 300
pollingInterval 轮询间隔(ms),0 表示不轮询 number 0
ready 请求依赖,true 时发起请求 boolean \| Ref<boolean> true
withToken 是否在请求头中携带 Token boolean true
showLoading 是否显示全局 uni.showLoading boolean false
showError 是否在错误拦截器中显示 uni.showToast boolean true

useRequest 返回值

参数 说明 类型
data 响应数据 Ref<T \| undefined>
loading 是否正在请求 Ref<boolean>
error 错误对象 Ref<Error \| null>
polling 是否正在轮询 Ref<boolean>
run 手动触发请求的函数 (...args) => Promise<T>
cancel 取消当前请求的函数 () => void
refresh 使用上次参数重新请求 () => Promise<T>
clearCache 清除当前请求的缓存 () => void
startPolling 开始轮询 () => void
stopPolling 停止轮询 () => void

完整使用示例 (场景化)

请注意:以下代码旨在提供 useRequest hook 的各种使用场景示例,不可直接运行。正确的用法是将 useRequest 导入到你的 Vue 组件的 <script setup> 中使用。

import { useRequest } from "./index";
import { ref, watch, computed, Ref } from "vue";

// 定义一些可能用到的类型
type UserInfo = {
  userId: string;
  username: string;
  avatar: string;
};

type Article = {
  id: number;
  title: string;
  content: string;
};

// --- 示例场景 ---

/**
 * 场景1: 基础用法 - 自动获取用户信息
 * 组件挂载后,自动请求并展示用户信息。
 */
function useUserProfile() {
  const {
    data: userProfile,
    loading,
    error,
  } = useRequest<UserInfo>("/api/user/profile");

  // 使用 watch 监听数据变化
  watch(userProfile, (newUser) => {
    if (newUser) {
      console.log("用户信息已更新:", newUser.username);
    }
  });

  // 在模板中可以直接使用 userProfile, loading, error
  // <view v-if="loading">加载中...</view>
  // <view v-if="userProfile">欢迎, {{ userProfile.username }}</view>
}

/**
 * 场景2: 手动触发 - 登录操作
 * 点击按钮后,手动调用 `run` 方法来发起登录请求。
 */
function useLogin() {
  const loginForm = ref({
    username: "test",
    password: "123",
  });

  const { run: performLogin, loading: isLoggingIn } = useRequest(
    "/api/auth/login",
    {
      manual: true,
      method: "POST",
    }
  );

  const onLoginClick = async () => {
    try {
      // run 方法可以接受参数,这些参数会作为请求的 data
      const token = await performLogin(loginForm.value);
      uni.setStorageSync("token", token);
      uni.showToast({ title: "登录成功" });
    } catch (e) {
      // 错误已由全局错误拦截器处理,这里可以不写
      console.error("登录失败,具体原因已由拦截器提示。");
    }
  };

  // 在模板中绑定 onLoginClick 到按钮上
  // <button @click="onLoginClick" :loading="isLoggingIn">登录</button>
}

/**
 * 场景3: 依赖请求 - 编辑时获取文章详情
 * 只有当文章ID存在时,才发起请求获取详情。
 */
function useArticleDetail(articleId: Ref<number | null>) {
  const { data: article, loading } = useRequest<Article>(
    (id) => `/api/article/${id}`, // URL 可以是一个函数
    {
      // 当 `articleId` 有有效值时,`ready` 才为 true
      ready: computed(() => !!articleId.value),
    }
  );

  // 当外部的 articleId 变化时,如果它不为 null,请求会自动发起
  // 例如:
  // articleId.value = 123; // 这会触发请求
}

/**
 * 场景4: 缓存 - 获取城市列表
 * 城市列表这类不经常变动的数据,非常适合使用缓存。
 */
function useCityList() {
  const { data: cityList, loading } = useRequest("/api/cities", {
    cacheTime: 10 * 60 * 1000, // 缓存10分钟
  });

  // 在10分钟内,多次调用 useCityList 不会发出新的网络请求
}

/**
 * 场景5: 取消请求
 * 演示如何取消一个正在进行的请求。
 */
function useCancellableRequest() {
  const { run, cancel, loading } = useRequest("/api/slow-request", {
    manual: true,
  });

  const startRequest = () => {
    run();
    // 模拟一个场景:如果请求在2秒内没有完成,就自动取消它
    setTimeout(() => {
      if (loading.value) {
        console.log("请求超时,正在取消...");
        cancel();
      }
    }, 2000);
  };
}

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

暂无用户评论。

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问