二.axios请求弹出确认窗口,点击取消如何终止请求

249 阅读1分钟

背景

项目中经常遇到删除数据时先弹出一个确认窗口,当点击确认才发送请求删除数据,本文使用axios实现统一封装

微信截图_20240308114005.png

常规做法

<template>
  <el-button @click="onRemove">删除</el-button>
</template>

<script setup>
import axios from 'axios';
async function remove(data) {
  await axios({
    url: '/delete',
    method: 'POST',
    data
  })
}

const onRemove = async () => {
  await ElMessageBox.confirm(`确认删除?`, '提示', {
    type: 'warning'
  })
  remove()
}
</script>

axios拦截器原理使用promise任务链的方式进行封装,可返回pending状态promise终止后续拦截器

Snipaste_2024-03-18_09-48-47.png

Snipaste_2024-03-18_09-51-38.png

封装axios拦截

使用终止promise任务链的方式

//使用方式
function remove(data) {
  axios({
    url: '/delete',
    method: 'POST',
    data,
    action: {
        confirm: true,
        text: `确认删除?`
      }
  })
}

var instance = axios.create({
    baseURL: '/api1,
  timeout: 20000
})

// 点击删除弹窗, 点击取消按钮, 终止axios请求
handleInterceptorAction(instance)

import { get } from 'lodash-es'
import { ElMessage } from 'element-plus'
// 增加 / 删除 请求确认
function handleInterceptorAction(instance) {
  instance.interceptors.request.use(async (config) => {
    let { action } = config

    // 判断是否需要弹窗, 没有传action.config 直接跳过
    if (!get(action, 'confirm')) return config

    try {
      await ElMessageBox.confirm(`${action.text}?`, '提示', {
        type: 'warning'
      })
      return config
    } catch (err) {
      // 如果点击取消,返回
      return new Promise(() => {})
    }
  })

  instance.interceptors.response.use((response) => {
    let { config, data } = response

    if (!config.action) return response

    // 处理请求失败
    ElMessage({
      type: data.IsSuccess ? 'success' : 'error',
      message: config.action.text + ' ' + data.Message
    })

    if (!data.IsSuccess) return Promise.reject({ text: config.action.text + ' ' + data.Message })

    return response
  })
}

全部代码

<template>
  <el-button @click="onRemove">删除</el-button>
</template>

<script setup>
import axios from 'axios';
import { get } from 'lodash-es'
import { ElMessage } from 'element-plus'

var instance = axios.create({
    baseURL: '/api1,
  timeout: 20000
})

// 点击删除弹窗, 点击取消按钮, 终止axios请求
handleInterceptorAction(instance)


// 增加 / 删除 请求确认
function handleInterceptorAction(instance) {
  instance.interceptors.request.use(async (config) => {
    let { action } = config

    // 判断是否需要弹窗, 没有传action.config 直接跳过
    if (!get(action, 'confirm')) return config

    try {
      await ElMessageBox.confirm(`${action.text}?`, '提示', {
        type: 'warning'
      })
      return config
    } catch (err) {
      // 如果点击取消,返回
      return new Promise(() => {})
    }
  })

  instance.interceptors.response.use((response) => {
    let { config, data } = response

    if (!config.action) return response

    // 处理请求失败
    ElMessage({
      type: data.IsSuccess ? 'success' : 'error',
      message: config.action.text + ' ' + data.Message
    })

    if (!data.IsSuccess) return Promise.reject({ text: config.action.text + ' ' + data.Message })

    return response
  })
}

function remove(data) {
  axios({
    url: '/delete',
    method: 'POST',
    data,
    action: {
        confirm: true,
        text: `确认删除?`
      }
  })
}

const onRemove = async () => {
  remove()
}
</script>