(一)vue3项目初始化(create-vue)

  1. npm create vite@latest 项目名称(根据提示如下图所示,选择需要的功能)
    在这里插入图片描述
  2. 配置Element-plus
yarn add element-plus

// 按需导入
yarn -D unplugin-vue-components unplugin-auto-import
  1. 更改vite配置
// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'

export default defineConfig({
  // ...
  plugins: [
    // ...
    AutoImport({
      resolvers: [ElementPlusResolver()],
    }),
    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ],
})

// 页面中使用
<el-button style="width: 100%;" type="primary">按 钮</el-button>
  1. pinia数据持久化
yarn add pinia-plugin-persistedstate
// store目录下新增index.ts, 将main.ts中需要引入的createPinia放到这儿,配置持久化
import { createPinia } from "pinia";
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia();
pinia.use(piniaPluginPersistedstate)
export default pinia;
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const doubleCount = computed(() => count.value * 2)
  function increment() {
    count.value++
  }

  return { count, doubleCount, increment }
}, {
  persist: true // 此处配置是否需要支持持久化
})

  1. 配置请求方法(axios)
// 安装axios
yarn add axios

// 创建request.ts
import axios from 'axios';
// 创建全局 AbortController 缓存(按请求URL+参数缓存)
const abortControllerMap = new Map();

// 生成唯一请求标识(用于缓存控制器)
const generateRequestId = (config: any) => {
  return `${config.url}`;
};

const service = axios.create({
  baseURL: import.meta.env.VITE_API_URL,
  timeout: 500000,
});

service.interceptors.request.use(
  (config) => {
    // 生成请求标识
    const requestId = generateRequestId(config);
    
    // 如果已有相同请求则中断前一个
    if (abortControllerMap.has(requestId) && config.abortable) {
      abortControllerMap.get(requestId).abort();
    }

    // 创建新控制器并缓存
    const controller = new AbortController();
    config.signal = controller.signal;
    abortControllerMap.set(requestId, controller);

    const { token } = JSON.parse(localStorage.getItem('x-userInfo') || '{}');
    if (token) {
      config.headers['Authorization'] = `Bearer ${token}`;
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

service.interceptors.response.use(
  (response) => {
    const res = response.data;
    const requestId = generateRequestId(response.config);
    
    // 请求完成后清理缓存控制器
    if (abortControllerMap.has(requestId)) {
      abortControllerMap.delete(requestId);
    }

    // 二进制数据则直接返回
    if (
      response.request.responseType === "blob" ||
      response.request.responseType === "arraybuffer"
    ) {
      return res;
    }

    if (res.error_code === 400004) {
    //   message.error(res.message || '您还未登录,请先去登录');
      return Promise.reject(res);
    } else if (res.error_code !== 0) {
    //   message.error(res.message || 'Error');
      return Promise.reject(new Error(res.message || 'Error'));
    } else {
      return res;
    }
  },
  (error) => {
    // 如果是取消请求导致的错误(code:ERR_CANCELED)
    if (axios.isCancel(error)) {
      console.log('请求被取消:', error.message);
      return Promise.reject({ 
        type: 'abort', 
        message: 'Request canceled' 
      });
    }
    
    console.log('请求错误 ', error);
    // message.error(error.message);
    return Promise.reject(error);
  }
);

// 封装带中断能力的get请求
export function get(url: any, params: any, config = {}) {
  return service({
    url,
    method: 'get',
    params,
    ...config,
  });
}

// 封装带中断能力的post请求
export function post(url: string, data: any, config = {}) {
  return service({
    url,
    method: 'post',
    data,
    ...config,
  });
}

// 新增:全局取消指定请求的方法
export function cancelRequest(config: any) {
  const requestId = generateRequestId(config);
  if (abortControllerMap.has(requestId)) {
    abortControllerMap.get(requestId).abort();
    return true;
  }
  return false;
}

// 新增:取消所有未完成请求
export function cancelAllRequests() {
  abortControllerMap.forEach(controller => controller.abort());
  abortControllerMap.clear();
}

export default service;
// 登录
import request from '@/utils/request';

export function loginApi(data) {
    return request({
        url: '/app/user/login',
        method: 'post',
        data,
        abortable: true
    })
}

// 此时request会有红色波浪线提示错误
// 可以在全局global.d.ts配置
declare module 'axios' {
    interface AxiosRequestConfig {
        abortable?: boolean;
    }
}
  1. 如果没有登录跳转到登录页面
// src同级增加permission.ts文件
import router from '@/router';

router.beforeEach((to, from, next) => {
  if (to.name !== 'login' && !localStorage.getItem('token')) {
    next({ name: 'login' })
  } else {
    next()
  }
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值