一般來說,項目由子模塊組成,拿到後端提供過來的介面,一般也是按照子模塊來分類提供的.請教一下各位,你們前端項目是如何管理api的? 希望各位貼點你們的優秀代碼段上來學習學習. 常見: 各個模塊的api存放到單獨的js文件里,返回一個請求實例promise對象 使用的時候根據需求引入相應的請求方法 / ...
一般來說,項目由子模塊組成,拿到後端提供過來的介面,一般也是按照子模塊來分類提供的.請教一下各位,你們前端項目是如何管理api的?
希望各位貼點你們的優秀代碼段上來學習學習.
常見:
各個模塊的api存放到單獨的js文件里,返回一個請求實例promise對象
使用的時候根據需求引入相應的請求方法
// axios/request.js 文件:
/* 創建axios請求實例,並返回實例 代碼就不貼上來了*/
// axios/apis/home.js 文件: import request from "../request"; //獲取菜單 export function getHomeNav(params) { return request({ url: "/api/home/getNav", params: params }); } //獲取熱門新聞 export function getHotNewsList(params) { return request({ url: "/api/home/getHotNewsList", params: params }); }
// axios/apis/my.js 文件: // 獲取用戶信息 export function getUserInfo(params) { return request({ url: "/api/get/user/info", params: params }); } // 更新用戶信息 export function updateUserInfo(params) { return request({ url: "/api/post/user/update", data: params }); }
// 使用文件: import { getHomeNav, getHotNewsList } from '@/axios/apis/home.js'
import { getUserInfo, updateUserInfo} from '@/axios/apis/home.js'
getHomeNav({}).then(res=>{ console.log(res) });
個人在某個項目上,煩透了在使用的時候一個個api請求方法引入.花了點時間,改成了所有api直接掛在一個全局變數上.犧牲了點性能,但是使用起來爽歪歪的感覺.
假如axios/apis/home.js文件: export default { //獲取菜單 nav: { url: "/api/home/getNav", method: "get", config:{timeout:50000} // 會覆蓋到axios實例的config對應的屬性 }, body: { //getHotNewsList getHotNewsList: { url: "/api/home/getHotNewsList", method: "get", }, //getList getList: { url: "/api/home/getList", method: "get", }, }, };
全局引入所有API:
import requireApi from '@/axios/index.js'
const APIS = requireApi();
home里的api調用可以這樣:
APIS.home.nav({page:1,sizePages:20}).then(res=>{ ... })
APIS.home.body.getHotNewsList({page:1,sizePages:20}).then(res=>{ ... })
假如另外有一個my的模塊api,使用起來可以這樣:
APIS.my.xxxx().then(res=>{ ... });
下麵是實現代碼段:// 假如目前有兩個模塊的api,分別存放在home.js,my.js里
// axios/apis/home.js文件:
export default { //獲取菜單 nav: { url: "/api/home/getNav", method: "get", config:{timeout:50000} // 會覆蓋到axios實例的config對應的屬性 }, body: { //getHotNewsList getHotNewsList: { url: "/api/home/getHotNewsList", method: "get", }, //getList getList: { url: "/api/home/getList", method: "get", }, }, };
// axion/apis/my.js文件:
export default { // 獲取用戶信息 getUserInfo: { url: "/api/get/user/info", method: "get", }, // 更新用戶信息 updateUserInfo: { url: "/api/post/user/update", method: "post", }, };
// axios/index.js 文件: import createApiFn from "./createApiFn"; /** * 把api文件夾下的所有Api文件require進來,在逐個export出去 * 假如axios/apis/home.js文件: export default { //獲取菜單 nav: { url: "/api/home/getNav", method: "get", config:{timeout:50000} // 會覆蓋到axios實例的config對應的屬性 }, body: { //getHotNewsList getHotNewsList: { url: "/api/home/getHotNewsList", method: "get", }, //getList getList: { url: "/api/home/getList", method: "get", }, }, }; * 按需求引入: * import { home } from '@/axios/index.js' * home.nav({page:1,sizePages:20}).then(res=>{ ... }) * home.body.getHotNewsList({page:1,sizePages:20}).then(res=>{ ... }) * * 全局引入所有API: * import requireApi from '@/axios/index.js' * const APIS = requireApi(); * APIS.home.nav({page:1,sizePages:20}).then(res=>{ ... }) * APIS.home.body.getHotNewsList({page:1,sizePages:20}).then(res=>{ ... }) */ /** // webpack let requireApi = () => { let allApi = require.context("./apis/", false, /\.js$/), allApiFnObj = {}; allApi.keys().map((item) => { allApiFnObj[item.replace(/(\.\/|\.js)/g, "")] = createApiFn(allApi(item).default); }); return allApiFnObj; }; */ // vite let requireApi = () => { let allApi = import.meta.globEager('./apis/*.js'), allApiFnObj = {}; Object.keys(allApi).map((item) => { const fileName = item.replace(/\.\/apis\/|\.js/g, ''); allApiFnObj[fileName] = createApiFn(allApi[item].default); }); return allApiFnObj; }; export default requireApi; // 需要手動把各個模塊export出去 let { home, my } = requireApi(); export { home, my };
// axios/createApiFn.js文件: import requestInstance from "./request"; const bindPromiseFn = (apiObj, args, config={}) => { const params = { method: apiObj.method || "get", url: apiObj.url, params: args, config: apiObj.config || {}, }; params.config = { ...params.config, ...config } return requestInstance(params); }; /** * 把apis對象轉變成以欄位名為方法名的對象 * 如: * apis={ * getDemo:{ * url:"xxxx", * method: "get" * }, * postDemo:{} * } * 執行方法後返回對象結構如下: * { * getDemo:function(){}, * postDemo:function(){} * } * @param {object} apis */ const createApiFn = (apis) => { var obj = {}; Object.keys(apis).map((key) => { if (apis[key] && apis[key].url) { obj[key] = (function (apiObj) { /** * args 請求入參 * config 請求配置相關信息,最終會傳給實例axios.config */ return function (args,config={}) { return bindPromiseFn(apiObj, args, config); }; })(apis[key]); } else if ( apis[key] && !apis[key].url && Object.prototype.toString.call(apis[key]) === "[object Object]") { obj[key] = createApiFn(apis[key]); } }); return obj; }; export default createApiFn;
// axios/request.js 文件: import axios from "axios"; // 創建axios實例 const axiosInstance = (config = {}) => { const _config = { // baseURL: `${location.protocol}//${process.env.VUE_APP_BASE_API}`, // `baseURL` 將自動加在 `url` 前面,除非 `url` 是一個絕對 URL。 timeout: 30000, }; config = { ..._config, ...config }; return axios.create(config); }; const requestInstance = (args) => { let { method, url, params, config = {} } = args; if (!url) { return; } if (method === "get") { params = { params: params }; } const instance = axiosInstance(config); instance.interceptors.request.use( (config) => { // config.headers["x-auth-token"] = getToken(); // 讓每個請求攜帶自定義token 請根據實際情況自行修改 return config; }, (error) => { return Promise.reject(error); } ); instance.interceptors.response.use( (response) => { const { status, statusText, data } = response if (status === 200 || status === 304) { return Promise.resolve(data); } else { return Promise.reject(statusText || "Error"); } }, (error) => { return Promise.reject(error); } ); debugger; return instance[method](url, params, config); }; export default requestInstance;
//全局引入所有API使用方法: import requireApi from '../axios/index' const API = requireApi(); API.my.updateUserInfo({name:'xiaomou'}).then(res=>{ console.log(res); }) APIS.home.body.getHotNewsList({page:1,sizePages:20}).then(res=>{ ... }) //按需求引入方法: import { home } from '@/axios/index.js' home.body.getHotNewsList({page:1,sizePages:20}).then(res=>{ ... })