记一个有意思的写法

api.js

javascript 复制代码
import { request } from '@fesjs/fes';
import { ref, isRef } from 'vue';
import { FMessage } from '@fesjs/fes-design';

const postApiWithBizUrl = {
    // 查询产品
    productQuery: '/product/query',
    // 添加/修改产品
    productOperate: '/product/operate',
    // 查询审批链
    approvalQuery: '/approval/query',
    // 查询文章
    articleQuery: '/article/query',
    // 删除文章
    articleDelete: '/article/delete',
    // 撤回文章
    withdraw: '/article/withdraw',
    // 添加/修改文章
    articleOperate: '/article/operate',
    // 查询权限
    umQuery: '/um/query',
    // 发布
    publish: '/publish',
    // 提交审批
    approvalCommit: '/approval/commit',
    // 下架
    offshelve: '/offshelve',
    // 添加标签
    tagInsert: '/tag/insert',
    // 取消发布
    unpublish: '/unpublish',
    // 查询单组标签
    tagQuery: '/tag/query',
    // 配置临期提醒
    articleConfigremind: '/article/configremind',
    // 删除临期提醒
    articleDeleteremind: '/article/deleteremind',
};

const getApiMap = {
    // 下载文件
    fileDownload: '/file/download',
    // 下载产品信息管理模板
    jrxxProductInfoTmplDownload: '/article/query/jrxx_pi/productinfo/download',
};

const postApiMap = {
    // 查询产品信息
    queryJrxxProductInfo: '/article/query/jrxx_pi/productinfo',
    // 查询复核记录 核查页面补上/check前缀  /check/query
    checkQuery: '/query',
    // 导航菜单查询单独使用查询待核查数据
    checkQueryVerified: '/check/query',
    // 查询变更记录-产品信息配置
    queryJrxxProductInfoHistory: '/article/operate/jrxx_pi/productinfo/history',
    // 更新产品信息配置
    operateJrxxProductInfo: '/article/operate/jrxx_pi/productinfo',
    // 核查操作 核查页面补上/check前缀  /check/operate
    checkOperate: '/operate',
};

const BASE_URL = process.env.FES_APP_BASE_URL;
console.log('process.env', process.env);
console.log('BASE_URL', BASE_URL);
let getUrlPrefix = () => '';
const middleWare = (apiMap, method = 'post', withBizUrl) => {
    const API = {};
    Object.entries(apiMap).forEach(([fnName, url]) => {
        API[fnName] = (params, { bizUrl, urlPrefix, ...options } = {}) => {
            urlPrefix = urlPrefix || getUrlPrefix() || '';
            const fullUrl = urlPrefix + url;
            return request(withBizUrl && bizUrl ? `${fullUrl}/${isRef(bizUrl) ? bizUrl.value : bizUrl}` : fullUrl, params, {
                mergeRequest: true,
                method,
                ...options,
            }).catch((err) => {
                if (err?.data?.msg) FMessage.error(err?.data?.msg);
                return Promise.reject(err);
            });
        };
    });
    return API;
};
export const setUrlPrefix = (prefix) => {
    getUrlPrefix = () => prefix;
};

export const API = { ...middleWare(postApiMap), ...middleWare(postApiWithBizUrl, 'post', true), ...middleWare(getApiMap, 'get') };

const hooksMiddlerWare = (apiObj, settings) => {
    let outBizUrl;
    let urlPrefix = '';
    if (typeof settings === 'string') {
        outBizUrl = settings;
    } else {
        outBizUrl = settings?.bizUrl;
        urlPrefix = settings?.urlPrefix ?? urlPrefix;
    }
    const hooks = {};
    Object.entries(apiObj).forEach(([hookName, apiFn]) => {
        hooks[hookName] = (bizUrl = outBizUrl) => {
            const loading = ref(false);
            const requestFn = (params, options) => {
                loading.value = true;
                return apiFn(params, { bizUrl, ...options, urlPrefix })
                    .then((res) => {
                        loading.value = false;
                        return Promise.resolve(res);
                    })
                    .catch((err) => {
                        loading.value = false;
                        return Promise.reject(err);
                    });
            };
            return [loading, requestFn];
        };
    });
    return hooks;
};

export const ApiHooks = hooksMiddlerWare(API);
export const useApiHooks = (bizUrl) => hooksMiddlerWare(API, bizUrl);

页面使用

javascript 复制代码
<script setup>
import { useApiHooks } from '@/services/api';

const ApiHooks = useApiHooks({ bizUrl, urlPrefix: route?.query?.mode === 'verify' ? '/check' : '' });
const [articleQueryLoading, articleQuery] = ApiHooks.articleQuery();
// 控制页面loading
        const loading = computed(() =>
            [
                articleQueryLoading,
                publishLoading,
                approvalCommitLoading,
                deleteLoading,
                withdrawLoading,
                offshelveLoading,
                fileDownloadLoading,
                unpublishLoading,
            ].some((i) => Boolean(i?.value)),
        );
</script>
相关推荐
代码煮茶6 小时前
Vite 5.0 新特性深度解析:更快、更干净、更未来的前端构建利器
vue.js
Pu_Nine_910 小时前
IntersectionObserver 详解:封装 Vue 指令实现图片懒加载
前端·javascript·vue.js·性能优化
前端那点事11 小时前
Vue nextTick 超全解析|作用、使用场景、底层原理、Vue2/Vue3区别
前端·vue.js
前端那点事11 小时前
Vue面试高频:子组件能直接修改父组件数据吗?单向数据流原理+正确写法全覆盖
前端·vue.js
前端那点事11 小时前
为什么 Vue 的 template 标签不能用 v-show?底层机制+踩坑复盘+生产级解决方案
前端·vue.js
北风toto13 小时前
为什么 IntelliJ IDEA Community 无法开发 Vue?——附解决方案
java·vue.js·intellij-idea
跟着珅聪学java13 小时前
Element UI 的 Tabs 标签页开发教程
javascript·vue.js·elementui
jiayong2314 小时前
前端面试题库 - Vue框架篇
前端·vue.js·面试
三*一14 小时前
Mapbox GL JS 前端多边形分割实战:从踩坑到优雅实现
开发语言·前端·javascript·vue.js
xChive14 小时前
前端请求取消:用 AbortController 从 fetch 到 axios
前端·vue.js·axios·fetch·abortcontroller