不是吧,不是吧,原来真的有人都2021年了,连TypeScript都没听说过吧?在我的项目中应用TypeScript尽管短期内会减少一些开发成本,然而对于其须要长期保护的我的项目,TypeScript可能缩小其保护老本,应用TypeScript减少了代码的可读性和可维护性,且领有较为沉闷的社区,当居为大前端的趋势所在,那就开始淦起来吧~
应用TypeScript封装根底axios库
代码如下:
// http.tsimport axios, { AxiosRequestConfig, AxiosResponse } from 'axios'import { ElMessage } from "element-plus"const showStatus = (status: number) => { let message = '' switch (status) { case 400: message = '申请谬误(400)' break case 401: message = '未受权,请从新登录(401)' break case 403: message = '回绝拜访(403)' break case 404: message = '申请出错(404)' break case 408: message = '申请超时(408)' break case 500: message = '服务器谬误(500)' break case 501: message = '服务未实现(501)' break case 502: message = '网络谬误(502)' break case 503: message = '服务不可用(503)' break case 504: message = '网络超时(504)' break case 505: message = 'HTTP版本不受反对(505)' break default: message = `连贯出错(${status})!` } return `${message},请查看网络或分割管理员!`}const service = axios.create({ // 联调 // baseURL: process.env.NODE_ENV === 'production' ? `/` : '/api', baseURL: "/api", headers: { get: { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' }, post: { 'Content-Type': 'application/json;charset=utf-8' } }, // 是否跨站点访问控制申请 withCredentials: true, timeout: 30000, transformRequest: [(data) => { data = JSON.stringify(data) return data }], validateStatus() { // 应用async-await,解决reject状况较为繁琐,所以全副返回resolve,在业务代码中解决异样 return true }, transformResponse: [(data) => { if (typeof data === 'string' && data.startsWith('{')) { data = JSON.parse(data) } return data }] })// 申请拦截器service.interceptors.request.use((config: AxiosRequestConfig) => { //获取token,并将其增加至申请头中 let token = localStorage.getItem('token') if(token){ config.headers.Authorization = `${token}`; } return config}, (error) => { // 谬误抛到业务代码 error.data = {} error.data.msg = '服务器异样,请分割管理员!' return Promise.resolve(error)})// 响应拦截器service.interceptors.response.use((response: AxiosResponse) => { const status = response.status let msg = '' if (status < 200 || status >= 300) { // 解决http谬误,抛到业务代码 msg = showStatus(status) if (typeof response.data === 'string') { response.data = { msg } } else { response.data.msg = msg } } return response}, (error) => { if (axios.isCancel(error)) { console.log('repeated request: ' + error.message) } else { // handle error code // 谬误抛到业务代码 error.data = {} error.data.msg = '申请超时或服务器异样,请查看网络或分割管理员!' ElMessage.error(error.data.msg) } return Promise.reject(error)})export default service
勾销多次重复的申请版本
在上述代码退出如下代码:
// http.tsimport axios, { AxiosRequestConfig, AxiosResponse } from 'axios'import qs from "qs"import { ElMessage } from "element-plus"// 申明一个 Map 用于存储每个申请的标识 和 勾销函数const pending = new Map()/** * 增加申请 * @param {Object} config */const addPending = (config: AxiosRequestConfig) => { const url = [ config.method, config.url, qs.stringify(config.params), qs.stringify(config.data) ].join('&') config.cancelToken = config.cancelToken || new axios.CancelToken(cancel => { if (!pending.has(url)) { // 如果 pending 中不存在以后申请,则增加进去 pending.set(url, cancel) } })}/** * 移除申请 * @param {Object} config */const removePending = (config: AxiosRequestConfig) => { const url = [ config.method, config.url, qs.stringify(config.params), qs.stringify(config.data) ].join('&') if (pending.has(url)) { // 如果在 pending 中存在以后申请标识,须要勾销以后申请,并且移除 const cancel = pending.get(url) cancel(url) pending.delete(url) }}/** * 清空 pending 中的申请(在路由跳转时调用) */export const clearPending = () => { for (const [url, cancel] of pending) { cancel(url) } pending.clear()}// 申请拦截器service.interceptors.request.use((config: AxiosRequestConfig) => { removePending(config) // 在申请开始前,对之前的申请做查看勾销操作 addPending(config) // 将以后申请增加到 pending 中 let token = localStorage.getItem('token') if(token){ config.headers.Authorization = `${token}`; } return config}, (error) => { // 谬误抛到业务代码 error.data = {} error.data.msg = '服务器异样,请分割管理员!' return Promise.resolve(error)})// 响应拦截器service.interceptors.response.use((response: AxiosResponse) => { removePending(response) // 在申请完结后,移除本次申请 const status = response.status let msg = '' if (status < 200 || status >= 300) { // 解决http谬误,抛到业务代码 msg = showStatus(status) if (typeof response.data === 'string') { response.data = { msg } } else { response.data.msg = msg } } return response}, (error) => { if (axios.isCancel(error)) { console.log('repeated request: ' + error.message) } else { // handle error code // 谬误抛到业务代码 error.data = {} error.data.msg = '申请超时或服务器异样,请查看网络或分割管理员!' ElMessage.error(error.data.msg) } return Promise.reject(error)})export default service
在路由跳转时撤销所有申请
在路由文件index.ts中退出
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'import Login from '@/views/Login/Login.vue'//引入在axios暴露出的clearPending函数import { clearPending } from "@/api/axios"............const router = createRouter({ history: createWebHistory(process.env.BASE_URL), routes})router.beforeEach((to, from, next) => { //在跳转路由之前,先革除所有的申请 clearPending() // ... next()})export default router
应用封装的axios申请库
封装响应格局
// 接口响应通过格局export interface HttpResponse { status: number statusText: string data: { code: number desc: string [key: string]: any }}
封装接口办法
举个栗子,进行封装User接口,代码如下~
import Axios from './axios'import { HttpResponse } from '@/@types'/** * @interface loginParams -登录参数 * @property {string} username -用户名 * @property {string} password -用户明码 */interface LoginParams { username: string password: string}//封装User类型的接口办法export class UserService { /** * @description 查问User的信息 * @param {number} teamId - 所要查问的团队ID * @return {HttpResponse} result */ static async login(params: LoginParams): Promise<HttpResponse> { return Axios('/api/user', { method: 'get', responseType: 'json', params: { ...params }, }) } static async resgister(params: LoginParams): Promise<HttpResponse> { return Axios('/api/user/resgister', { method: 'get', responseType: 'json', params: { ...params }, }) }}
我的项目中进行应用
代码如下:
<template> <input type="text" v-model="Account" placeholder="请输出账号" name="username" > <input type="text" v-model="Password" placeholder="请输出明码" name="username" > <button @click.prevent="handleRegister()">登录</button></template><script lang="ts">import { defineComponent, reactive, toRefs } from 'vue'//引入接口import { UserService } from '@/api/user'export default defineComponent({ setup() { const state = reactive({ Account: 'admin', //账户 Password: 'hhhh', //明码 }) const handleLogin = async () => { const loginParams = { username: state.Account, password: state.Password, } const res = await UserService.login(loginParams) console.log(res) } const handleRegister = async () => { const loginParams = { username: state.Account, password: state.Password, } const res = await UserService.resgister(loginParams) console.log(res) } return { ...toRefs(state), handleLogin, handleRegister } },})</script>