如何在VueUse的useAxios执行时补全URL?或用其删除条目?
VueUse useAxios 预定义基础URL并动态拼接ID实现DELETE请求
我正在开发一个调用REST API的Vue应用,使用VueUse的useAxios发起请求,现有如下可行代码(在Pinia store中运行正常):
const {data: todosList, isLoading, error, execute} = useAxios("/myapi/todos", {method: "GET"})
现在需要实现通过todo ID删除对应条目的功能,API要求发送DELETE请求到/myapi/todos/5(5为todo的ID)。我在Pinia store中定义了接收todo对象作为参数的deleteTodo函数,尝试了三种方案:
- 方案1:在
deleteTodo内创建useAxios实例
function deleteTodo(todo){ const {data, isLoading, error, execute} = useAxios("/myapi/todos/" + todo.id, {method: "DELETE"}).then(() => {todosList.value.splice(todosList.value.indexOf(team), 1)}) }
问题:无法将isLoading和error从Pinia store返回给组件使用。
- 方案2:提前创建请求实例,调用execute
const {data, isLoading, error, execute} = useAxios("/myapi/todos/", {method: "DELETE"}, {immediate: false}) function deleteTodo(todo){ execute().then(() => {todosList.value.splice(todosList.value.indexOf(todo), 1)}); // URL缺少todo ID,无效 }
问题:URL中缺少todo ID,请求无法正确命中目标资源。
- 方案3:提前创建无URL的实例,执行时传入完整URL
const {data, isLoading, error, execute} = useAxios({method: "DELETE"}, {immediate: false}) function deleteTodo(todo){ execute("/myapi/todos/" + todo.id).then(() => {todosList.value.splice(todosList.value.indexOf(todo), 1)}); // 执行时拼接ID构建完整URL }
问题:满足功能需求,但请求定义被拆分为两部分,写法不够优雅。
核心疑问
是否可以提前预定义基础URL,仅在调用execute时动态拼接todo的ID?类似如下伪代码的效果:
const {data, isLoading, error, execute} = useAxios("/myapi/todos/", {method: "DELETE"}, {immediate: false}) function deleteTodo(todo){ execute({urlSuffix: todo.id}).then(() => {todosList.value.splice(todosList.value.indexOf(todo), 1)}); // 仅在执行时拼接ID }
可行解决方案
可以通过两种方式实现预定义基础URL并动态拼接ID的需求:
- 利用
execute的参数覆盖URL并拼接execute方法支持传入新的请求配置,你可以基于预定义的基础URL,在调用时拼接ID:
const baseUrl = "/myapi/todos/" const {data, isLoading, error, execute} = useAxios(baseUrl, {method: "DELETE"}, {immediate: false}) function deleteTodo(todo){ // 拼接基础URL和ID,传入execute作为新的URL参数 execute(baseUrl + todo.id).then(() => { todosList.value.splice(todosList.value.indexOf(todo), 1) }) }
这种方式既保留了预定义的基础URL,又能动态拼接ID,写法更统一。
- 使用Axios的请求拦截器拼接URL
如果需要更通用的处理,可以在创建Axios实例时添加请求拦截器,自动处理URL拼接:
// 先创建自定义Axios实例 const axiosInstance = axios.create({ baseURL: "/myapi/" }) // 添加请求拦截器,处理URL拼接 axiosInstance.interceptors.request.use(config => { if (config.urlSuffix) { config.url += config.urlSuffix delete config.urlSuffix } return config }) // 在useAxios中使用自定义实例 const {data, isLoading, error, execute} = useAxios("todos/", {method: "DELETE"}, {immediate: false, axios: axiosInstance}) function deleteTodo(todo){ execute({urlSuffix: todo.id}).then(() => { todosList.value.splice(todosList.value.indexOf(todo), 1) }) }
这种方式适合多个请求都需要类似URL拼接逻辑的场景,复用性更强。
内容的提问来源于stack exchange,提问作者Jakob
相关产品推荐
相关产品推荐

