欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue3?typescript封裝axios過程示例

 更新時(shí)間:2022年10月19日 14:52:30   作者:ws_qy  
這篇文章主要為大家介紹了vue3?typescript封裝axios過程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

1.目錄層級(jí)

src目錄下分為5個(gè)文件夾。這里做簡(jiǎn)單處理,其中axios請(qǐng)求主要體現(xiàn)在api層,request層,config層和sevices層

2.request層

這里是封裝請(qǐng)求層,主要是使用axios的一些api封裝請(qǐng)求,我這里使用的是ts封裝

2.1請(qǐng)求主體

//services.ts
import axios from "axios";
import type {
  AxiosInstance,
} from "axios";
const service: AxiosInstance = axios.create({
  baseURL: "http://localhost:3000",
  timeout: 5000,
});
 export default service

2.2攔截器

攔截器主要包含請(qǐng)求攔截器和響應(yīng)攔截器,在請(qǐng)求攔截器中可以設(shè)置token,cookie,可以在請(qǐng)求頭中進(jìn)行各種操作

//interceptors.ts
import type { AxiosError, AxiosRequestConfig, AxiosResponse } from "axios";
import { ElMessage } from "element-plus";
import service from "./srevice";
service.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    //給請(qǐng)求頭設(shè)置token
    // if (token) {
    //   config.headers!.Authorization = `baseUrl ${token}`;
    // }
    return config;
  },
  (error: AxiosError) => {
    ElMessage.error(error.message);
    return Promise.reject(error);
  }
);
/* 響應(yīng)攔截器 */
service.interceptors.response.use(
  (response: AxiosResponse) => {
    const { code, message, data } = response.data; // 根據(jù)自定義錯(cuò)誤碼判斷請(qǐng)求是否成功
    if (code === 0) {
      // 將組件用的數(shù)據(jù)返回
      return data;
    } else {
      // 處理業(yè)務(wù)錯(cuò)誤。
      ElMessage.error(message);
      return Promise.reject(new Error(message));
    }
  },
  (error: AxiosError) => {
    // 處理 HTTP 網(wǎng)絡(luò)錯(cuò)誤
    let message = "";
    // HTTP 狀態(tài)碼
    const status = error.response?.status;
    switch (status) {
      case 401:
        message = "token失效,請(qǐng)重新登錄";
        // 這里可以觸發(fā)退出的 action
        break;
      case 403:
        message = "沒有權(quán)限,請(qǐng)獲取權(quán)限后登錄";
        break;
      case 404:
        message = "頁面不存在";
        break;
      case 500:
        message = "服務(wù)器故障";
        break;
      case 502:
        message = "數(shù)據(jù)庫查詢錯(cuò)誤";
        break;
      default:
        message = "網(wǎng)絡(luò)連接錯(cuò)誤";
    }
    ElMessage.error(message);
    return Promise.reject(error);
  }
);
export default service

2.3 封裝請(qǐng)求方法

import type {AxiosRequestConfig } from "axios";
import service from "./interceptors";
const httpObj = {
  get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
    return service.get(url, config);
  },
  post<T = any>(
    url: string,
    data?: object,
    config?: AxiosRequestConfig
  ): Promise<T> {
    return service.post(url, data, config);
  },
  put<T = any>(
    url: string,
    data?: object,
    config?: AxiosRequestConfig
  ): Promise<T> {
    return service.put(url, data, config);
  },
  delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
    return service.delete(url, config);
  },
};
export default httpObj;

3.api層

這一層級(jí)是為了封裝api請(qǐng)求,在這里我是根據(jù)頁面模塊功能進(jìn)行劃分,如home頁面所有請(qǐng)求就在home文件下,shop所有請(qǐng)求都在shop文件夾下,在index.ts中進(jìn)行引入,并導(dǎo)出,這么做的好處是我們?nèi)粘i_發(fā)中很容易根據(jù)頁面模塊去找到對(duì)應(yīng)的請(qǐng)求,協(xié)同開發(fā)中也不容易導(dǎo)致請(qǐng)求接口混亂

3.1細(xì)分功能模塊

//api/home/home.ts
import request from "../../request/index";
import services from "../../services/index";
let api = {
getTreeList: () => {
    return request.get(services.treeUrl);
  },
};
export default api;

3.2api層主體

//api/index.ts
import home from "./home/home"
let api = {
    home: { ...home},
  };
  export default api;

4.service層

這個(gè)層級(jí)主要是對(duì)接口中的url進(jìn)行統(tǒng)一模塊化管理,跟api層類似,分頁面模塊進(jìn)行分層

//services/home/home.ts
interface urlType {
    treeUrl: string;
  }
const url:urlType = {
  treeUrl: "/tree/getTreeList",
};
export default url
//services/index.ts
import home from "./home/home"
export default {
    ...home
}

5.將api層請(qǐng)求掛載到全局中

在vue3.0中不存在this,所以無法掛載this的原型上,因此需要調(diào)用它的一個(gè)api

//main.ts
import { createApp } from "vue";
import ElementPlus from "element-plus";
//引入elementui樣式
import 'element-plus/dist/index.css'
import App from "./App.vue";
//引入api層
import api from "./api/index"; 
const app = createApp(App);
//掛載api層
app.config.globalProperties.$api = api;
app.use(ElementPlus);
app.mount("#app");

在頁面中使用,新建view方頁面組件,components放公共組件,在view中添加home組件

//src/view/home.vue
<script setup lang="ts">
import { getCurrentInstance } from "vue";
//引入全局掛載變量
const { proxy }: any = getCurrentInstance();
//發(fā)送請(qǐng)求
const getTreeList = async (): Promise<void> => {
  const data = await proxy.$api.home.getTreeList();
  console.log(data);
};
//點(diǎn)擊事件
const getList = (): void => {
  getTreeList();
};
</script>
<template>
    <el-button type="primary" @click="getList">點(diǎn)擊</el-button>
</template>
<style scoped>
</style>

6.后端接口

這里的請(qǐng)求后端是我用express寫的簡(jiǎn)單服務(wù),這里簡(jiǎn)單做了路由層和請(qǐng)求serve層

db是數(shù)據(jù)源,因?yàn)闆]有引入sql數(shù)據(jù)庫,所以這里使用node簡(jiǎn)單對(duì)json數(shù)據(jù)文件進(jìn)行讀寫操作滿足簡(jiǎn)單的增刪改查操作,palyData用于操作數(shù)據(jù)json

6.1 express搭建本地服務(wù)

//serve/index.js
const express = require('express')
const app = express()
const tree=require('./router/tree')
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin','*');
    // 允許的header類型
    res.header('Access-Control-Allow-Headers','content-type');
    // 跨域允許的請(qǐng)求方式
    res.header('Access-Control-Allow-Methods','DELETE,PUT,POST,GET,OPTIONS');
    if (req.method === 'OPTIONS') {
        return res.send()
    }
    next()
})
app.use('/tree',tree)
app.listen(3000, () => {
    console.log('3000端口服務(wù)啟動(dòng)')
})

6.2路由層封裝

//serve/route/tree.js
const express = require('express')
const { readFile,writeFile} =require('../playData/playData')
const router=express.Router()
router.get('/getTreeList', (req, res) => {
    readFile((data) => {
        res.json(data)
    })
})
router.get('/deleteTreeList/:id', (req, res) => {
    let id = parseInt(req.params.id)
    readFile((data) => {
        let {
            parent,
            children
        } = data
        const newParent = parent.filter(item => item.id !== id)
        const newChildren = children.filter(item => item.id !== id)
        data.parent = newParent;
        data.children = newChildren;
        let json = JSON.stringify(data)
        let msg='刪除成功'
        writeFile(json,res,msg)
    })
})
router.post('/modifyTreeList', (req, res) => {
    const {data}=req.body
   let id=parseInt(data.id)
   let name=data.name;
   readFile((data) => {
    let {
        parent,
        children
    } = data
 parent.forEach(item => {
          if(item.id==id){
            item.name=name
          }
    })
children.forEach(item => {
        if(item.id==id){
          item.name=name
        }
  })
  data.parent = parent;
  data.children = children;
  let json = JSON.stringify(data)
  let msg='修改成功'
  writeFile(json,res,msg)
})
});
module.exports=router

6.3讀寫操作

//serve/playData/playData.js
const fs = require('fs')
const path = require('path')
const p=path.join(__dirname, '../db/index.json')
const readFile = (callBack) => {
    fs.readFile(p, 'utf8', (err, data) => {
        if (err) {
            return
        }
        callBack && callBack(JSON.parse(data))
    })
}
const writeFile=(json,res,msg)=>{
    fs.writeFile(p, json, (err) => {
        res.json({
            msg
        })
    })
}
module.exports={
    readFile,
    writeFile
}

7.總結(jié)

這篇文章主要是對(duì)axios的ts封裝進(jìn)行簡(jiǎn)單的探究,因?yàn)闆]有后端代碼,沒辦法進(jìn)行測(cè)試,因此使用了node,使用express框架搭建了一個(gè)本地服務(wù)。日常開發(fā)中封裝不僅僅是為了圖一時(shí)的方便簡(jiǎn)單,好的封裝代碼層級(jí)結(jié)構(gòu)也會(huì)方便項(xiàng)目后期的迭代化,避免到了項(xiàng)目后期,項(xiàng)目代碼變得臃腫而繁瑣,我覺得優(yōu)秀的代碼不是寫出來別人看不懂,一目了然的代碼才是好的代碼

以上就是vue3 typescript封裝axios過程示例的詳細(xì)內(nèi)容,更多關(guān)于vue3 typescript封裝axios的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論