隐藏

vue3 +ts 安装并封装axios

发布:2023/10/9 23:05:56作者:管理员 来源:本站 浏览次数:211

目录


1、为什么要封装axios


2、安装


3、封装request


4、使用步骤


步骤1:请求数据 ( 举例下面几个常用的 )


步骤2:在要请求的组件上使用


5、代理

1、为什么要封装axios


   axios.get().then()   这样的书写,会有缺陷,在以下缺点

   1、请求头能不能统一处理

       解决: 创建一个 request/request.js 文件夹,

           在里面可以使用axios.create创建实例对象

           也可以在里面设置  请求 与 响应 拦截器


   2、不便于接口的统一管理  

       解决:在 request 文件夹加多一个api文件来管理所有接口,

           (会先导入rerequest.js的实例)

           并使用函数,不然每次发请求时都会跑一次api文件


   3、容易出现回调地狱

       LogoutAPI () 最终的结果是返回proise对象

       解决:acync + await

       await 后面一般放promise对象


注意:但封装axios后还是可以用 .then()

2、安装


npm install axios


3、封装request


先在 src 下创建一个 request 文件夹,并添加一个  request.ts  文件


   import axios from 'axios'

   // 创建axios实例

   const request = axios.create({

       baseURL: '',// 所有的请求地址前缀部分(没有后端请求不用写)

       timeout: 80000, // 请求超时时间(毫秒)

       withCredentials: true,// 异步请求携带cookie

       // headers: {

       // 设置后端需要的传参类型

       // 'Content-Type': 'application/json',

       // 'token': x-auth-token',//一开始就要token

       // 'X-Requested-With': 'XMLHttpRequest',

       // },

   })

   

   // request拦截器

   request.interceptors.request.use(

       config => {

           // 如果你要去localStor获取token,(如果你有)

           // let token = localStorage.getItem("x-auth-token");

           // if (token) {

                   //添加请求头

                   //config.headers["Authorization"]="Bearer "+ token

           // }

           return config

       },

       error => {

           // 对请求错误做些什么

           Promise.reject(error)

       }

   )

   

   // response 拦截器

   request.interceptors.response.use(

       response => {

           // 对响应数据做点什么

           return response.data

       },

       error => {  

           // 对响应错误做点什么

           return Promise.reject(error)

       }

   )

   export default request


4、使用步骤


   注意:因为get请求的参数需要`params`,它是即将与请求一起发送的 URL 参数,为了简写采用了ES6的解构,就是把下面的 params 解构,只有get 请求需要加多一层`params`。


    其它请求,如 post 等请求等就不用解构,形参是什么都行。


步骤1:请求数据 ( 举例下面几个常用的 )


在 request 文件夹,再添加一个  api.ts  文件


   定义接口格式:


   export  const  自定义接口名  =  (形参:请求类型):返回类型  =>  instance.方法(路径,后端要的参数);


   import instance from "./request";

   

   //一般情况下,接口类型会放到一个文件

   // 下面两个TS接口,表示要传的参数

   interface ReqLogin {

       name: string

       paw: string

   }

   interface ReqStatus {

       id: string

       navStatus: string

   }

   

   

   // Res是返回的参数,T是泛型,需要自己定义,返回对数统一管理***

   type Res<T> = Promise<ItypeAPI<T>>;

   // 一般情况下响应数据返回的这三个参数,

   // 但不排除后端返回其它的可能性,

   interface ItypeAPI<T> {

       data: T,//请求的数据,用泛型

       msg: string | null // 返回状态码的信息,如请求成功等

       code: number //返回后端自定义的200,404,500这种状态码

   }

   

   

   // post请求 ,没参数

   export const LogoutAPI = (): Res<null> =>

       instance.post("/admin/logout");

   

   // post请求,有参数,如传用户名和密码

   export const loginAPI = (data: ReqLogin): Res<string> =>

       instance.post("/admin/login", data);

   

   // post请求 ,没参数,但要路径传参

   export const StatusAPI = (data: ReqStatus): Res<null> =>

       instance.post(`/productCategory?ids=${data.id}&navStatus=${data.navStatus}`);

   

   

   //  get请求,没参数,

   export const FlashSessionListApi = (): Res<null> =>

       instance.get("/flashSession/list");

   

   // get请求,有参数,路径也要传参  (也可能直接在这写类型,不过不建议,大点的项目会维护一麻烦)

   export const ProductCategoryApi = (params: { parentId: number }): any =>

       instance.get(`/productCategory/list/${params.parentId}`, { params });

   

   // get请求,有参数,(如果你不会写类型也可以使用any,不过不建议,因为用了之后 和没写TS一样)

   export const AdminListAPI = (params:any): any =>

       instance.get("/admin/list", { params });

   


步骤2:在要请求的组件上使用


使用方式一:直接使用(和vue2在cretae上用一样,setup自带async,await在顶层可以直接使用)


   <script setup lang="ts">

   import { indexAPI} from "../../request/api";

       //直接使用,一般用在进入页面入请求数据的接口

       let res = await indexAPI()

       console.log( "***" ,res);

   

   </script>


使用方式二:使用 async / await,(setup虽然自带async,但单独用await只能在顶层使用,如果在函数下还是要async / await一起写)


   <script setup lang="ts">

   import { returnApplyListAPi } from "../../request/api";

   

   const search = async(val: IUseTableParam) => {

       let res = await returnApplyListAPi({

           ...val,

       })

       console.log( "***" ,res);

       let { list, pageNum, pageSize, total } = res.data

       console.log(list, pageNum, pageSize, total);

   }

   </script>


使用方式三:使用.then


   <script setup lang="ts">

   import { returnApplyListAPi} from "../../request/api";

   

   const logout = () => {

       returnApplyListAPi({

           ...val,

       }).then((res) => {

            console.log('***',res );

           let { list, pageNum, pageSize, total } = res.data

       })

   

   };

   </script>


5、代理


   需要代理才写


上面的request 文件中


   const request = axios.create({

       //这时你要代理

       //填写后端统一的前缀,

       //如:123.xx.xx.xx:456/api/...

       //这个/api是每一个接口都有的,就写它

       //如果没有,也写,下面会讲区别

       baseURL: '/api',

   })


vite.config.ts 文件


   // https://vitejs.dev/config/

   export default defineConfig({

       plugins: [

           vue(),

           //...

       ],

       server: {

           proxy: {

               '/api': { // 匹配请求路径,

                   target: '你要代理的地址', // 代理的目标地址

                    // 开发模式,默认的127.0.0.1,开启后代理服务会把origin修改为目标地址

                   changeOrigin: true,

                   // secure: true, // 是否https接口

                   // ws: true, // 是否代理websockets

   

                   // 路径重写,**** 如果你的后端有统一前缀(如:/api),就不开启;没有就开启

                   //简单来说,就是是否改路径 加某些东西

                   rewrite: (path) => path.replace(/^\/api/, '')

               }

           }

       }

   })