当前位置:
首页 > 网站开发 > JavaScript >
-
前端如何相对优雅管理api
一般来说,项目由子模块组成,拿到后端提供过来的接口,一般也是按照子模块来分类提供的.请教一下各位,你们前端项目是如何管理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=>{ ... })
出处:https://www.cnblogs.com/xiaomou2014/p/17200411.html
栏目列表
最新更新
python爬虫及其可视化
使用python爬取豆瓣电影短评评论内容
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
uniapp/H5 获取手机桌面壁纸 (静态壁纸)
[前端] DNS解析与优化
为什么在js中需要添加addEventListener()?
JS模块化系统
js通过Object.defineProperty() 定义和控制对象
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比