Vue3 还原一个企业级后台-08-API注册管理
业务实现 1API 注册管理模块脚手架、布局、通用组件都就位了现在该上战场了。第一个业务模块——API 注册管理是整个项目的列表页范式样板间。把这一篇吃透后面两个业务模块模型汇聚、模型标准发布都是它的变体。一、业务理解API 注册管理是什么管网模型工具是 AI 模型生命周期管理后台。模型要被调用得先有 API。API 注册管理就是把后端已经写好的 API 登记到平台里供模型统一调用。打个比方平台是一个调度中心API 是可调用的能力清单。注册管理就是维护这份清单——谁提供了什么能力、怎么调用、现在能不能用。核心字段字段说明示例名称API 的展示名管网泄漏检测接口协议通信协议HTTP / HTTPS / gRPCURL接口地址https://api.pipe.com/leak-detect请求方式HTTP 方法GET / POST / PUT状态启用 / 禁用启用操作每个 API 有 5 个操作新增、编辑、删除、详情、调试。其中调试是本项目最有特色的功能——直接在平台里发请求看响应不用开 Postman。二、列表页实现用 AppTable 一路平推列表页是 API 注册管理的核心。有了第 7 篇封装的 AppTable整个列表页的 template 只有 20 行!-- views/api-manage/ApiRegistry.vue -- template div classpage-card AppBreadcrumb :items[{ title: API 注册管理 }] / !-- 筛选区 -- div classfilter-bar el-select v-modelfilters.protocol placeholder协议 clearable stylewidth: 140px el-option labelHTTP valueHTTP / el-option labelHTTPS valueHTTPS / el-option labelgRPC valuegRPC / /el-select el-select v-modelfilters.status placeholder状态 clearable stylewidth: 140px el-option label启用 valueenabled / el-option label禁用 valuedisabled / /el-select AppSearchInput v-modelfilters.keyword placeholder搜索 API 名称 searchonSearch / el-button typeprimary :iconPlus clickopenCreate新增 API/el-button /div !-- 表格 -- AppTable :datatableData :columnscolumns :loadingloading :totaltotal v-model:pagepage v-model:selectionselectedRows page-changefetchData template #status{ row } StatusTag :statusrow.status / /template template #action{ row } el-button typeprimary link clickgoDetail(row)详情/el-button el-button typeprimary link clickopenEdit(row)编辑/el-button el-button typedanger link clickdel(row)删除/el-button el-button typeprimary link clickgoDebug(row)调试/el-button /template /AppTable /div /template2.1 columns 配置columns数组告诉 AppTable 表格有哪些列、每列怎么渲染constcolumns[{prop:name,label:API 名称,width:200,align:left},{prop:protocol,label:协议,width:100,align:center},{prop:url,label:接口地址,minWidth:280,align:left},{prop:method,label:请求方式,width:100,align:center},{prop:status,label:状态,width:100,align:center,slot:status},{prop:createTime,label:创建时间,width:180,align:center}]注意status列配了slot: status——意思是这一列不用文本渲染用名为status的 slot。在 template 里我们写了template #status{ row }来渲染StatusTag组件。2.2 数据获取import{ref,reactive,onMounted}fromvueimport{getApiList}from/api/apiManageconsttableDataref([])consttotalref(0)constloadingref(false)constpageref(1)constpageSize30constfiltersreactive({protocol:,status:,keyword:})asyncfunctionfetchData(){loading.valuetruetry{constresawaitgetApiList({page:page.value,pageSize,...filters})tableData.valueres.data.list total.valueres.data.total}finally{loading.valuefalse}}onMounted(fetchData)fetchData是列表页的心脏——筛选条件变了、翻页了、搜索了都调它重新拉数据。它只关心拿数据不关心数据怎么展示——展示是 AppTable 的事。三、筛选 搜索逻辑多条件组合3.1 多条件组合筛选协议下拉 状态下拉 搜索框三个条件可以任意组合。实现方式很简单——把它们都放进filters对象调fetchData时一起传给后端MockfunctiononFilterChange(){page.value1// 筛选后回到第一页fetchData()}注意page.value 1——筛选后必须重置页码否则可能出现筛选后第 3 页没数据的尴尬。3.2 防抖搜索搜索框如果每敲一个字就发一次请求用户快速输入管网泄漏四个字会发 4 次请求。用 500ms 防抖等用户停下来再发import{debounce}from/utils/debounceconstonSearchdebounce((){page.value1fetchData()},500)debounce是一个 10 行的小工具函数// utils/debounce.jsexportfunctiondebounce(fn,delay300){lettimernullreturn(...args){clearTimeout(timer)timersetTimeout(()fn(...args),delay)}}3.3 筛选状态同步到 URL query这是一个加分项——把筛选条件写进 URL刷新页面后筛选条件还在。实现用useRouteuseRouterimport{useRoute,useRouter}fromvue-routerconstrouteuseRoute()constrouteruseRouter()// 初始化时从 URL 读取筛选条件onMounted((){const{protocol,status,keyword,page:p}route.queryif(protocol)filters.protocolprotocolif(status)filters.statusstatusif(keyword)filters.keywordkeywordif(p)page.valueNumber(p)fetchData()})// 筛选变化时写回 URLwatch(filters,(){router.replace({query:{...filters,page:page.value}})},{deep:true})原型阶段不做这个也完全 OK——但做了之后演示效果会好很多客户刷新页面数据不丢。四、复选框 批量操作跨页选择是难点4.1 选中行的获取AppTable 已经把selection-change事件封装好了父组件通过v-model:selection拿到选中行constselectedRowsref([])// 批量删除functionbatchDelete(){if(selectedRows.value.length0){ElMessage.warning(请先选择要删除的 API)return}ElMessageBox.confirm(确认删除选中的${selectedRows.value.length}个 API,批量删除,{type:warning}).then((){// 调用删除接口ElMessage.success(删除成功)fetchData()})}4.2 跨页保持选择第 7 篇提到AppTable 的复选框列设了:reserve-selectiontrue。这保证了用户在第 1 页选了 3 条、翻到第 2 页选了 2 条selectedRows里是 5 条而不是 2 条。但有个前提——el-table必须知道哪行是同一行靠row-key属性。AppTable 默认rowKey: id所以每条数据必须有唯一的id字段。Mock 数据里id生成的 id 正好满足。4.3 全选/反选/单选这些 Element Plus 表格自带不需要额外写代码。AppTable 只是把selection-change事件透传出来。五、行操作四个按钮各司其职行操作列的四个按钮对应四种交互操作行为实现详情跳转到详情页router.push(/api-manage/detail/ row.id)编辑打开编辑弹窗openEdit(row)删除带确认后删除ElMessageBox.confirm 删除接口调试跳转到运行调试 tabrouter.push(/api-manage/detail/ row.id ?tabdebug)import{useRouter}fromvue-routerconstrouteruseRouter()functiongoDetail(row){router.push(/api-manage/detail/${row.id})}functiongoDebug(row){router.push(/api-manage/detail/${row.id}?tabdebug)}functiondel(row){ElMessageBox.confirm(确认删除「${row.name}」,删除确认,{type:warning}).then(async(){awaitdeleteApi(row.id)ElMessage.success(删除成功)fetchData()}).catch((){})}删除操作必须带ElMessageBox.confirm二次确认——这是后台系统的铁律。误删一条生产数据后果可能很严重。六、详情页双 Tab 设计详情页是 API 注册管理最有特色的部分——它有两个 Tab基本信息 Tab只读展示 API 的所有字段运行调试 TabJSON 编辑器 Send 按钮 响应展示6.1 路由与页面结构// router 配置{path:api-manage/detail/:id,name:ApiDetail,component:()import(/views/api-manage/ApiDetail.vue),meta:{title:API 详情,module:/api-manage/registry,hidden:true}}!-- views/api-manage/ApiDetail.vue -- template div classpage-card el-button :iconArrowLeft clickgoBack返回/el-button AppBreadcrumb :items[{ title: API 注册管理, path: /api-manage/registry }, { title: API 详情 }] / el-tabs v-modelactiveTab tab-changeonTabChange el-tab-pane label基本信息 nameinfo / el-tab-pane label运行调试 namedebug / /el-tabs div v-showactiveTab info !-- 基本信息只读展示 -- el-descriptions :column2 border el-descriptions-item labelAPI 名称{{ detail.name }}/el-descriptions-item el-descriptions-item label协议{{ detail.protocol }}/el-descriptions-item el-descriptions-item label接口地址{{ detail.url }}/el-descriptions-item el-descriptions-item label请求方式{{ detail.method }}/el-descriptions-item el-descriptions-item label状态 StatusTag :statusdetail.status / /el-descriptions-item el-descriptions-item label描述 :span2{{ detail.description }}/el-descriptions-item /el-descriptions /div div v-showactiveTab debug !-- 运行调试 -- div classdebug-area div classdebug-request div classdebug-toolbar el-select v-modeldebugMethod stylewidth: 120px el-option labelGET valueGET / el-option labelPOST valuePOST / /el-select el-input v-modeldebugUrl readonly styleflex: 1 / el-button typeprimary :loadingdebugging clicksendRequestSend/el-button /div el-input v-modeldebugBody typetextarea :rows10 placeholder请求体JSON / /div div classdebug-response div classdebug-response-title响应/div pre{{ debugResult }}/pre /div /div /div /div /template6.2 运行调试的实现调试 Tab 的核心是一个假请求——因为后端还没好我们用 Mock 模拟响应import{ref,onMounted}fromvueimport{useRoute}fromvue-routerimport{getApiDetail}from/api/apiManageconstrouteuseRoute()constdetailref({})constactiveTabref(info)constdebugMethodref(GET)constdebugUrlref()constdebugBodyref({\n param: value\n})constdebugResultref()constdebuggingref(false)onMounted(async(){constresawaitgetApiDetail(route.params.id)detail.valueres.data debugUrl.valueres.data.url// 从 URL query 读取初始 tab?tabdebugif(route.query.tab)activeTab.valueroute.query.tab})asyncfunctionsendRequest(){debugging.valuetruetry{// 模拟请求延迟awaitnewPromise(rsetTimeout(r,800))debugResult.valueJSON.stringify({code:200,message:success,{leakProbability:0.87,location:[120.15,30.28],timestamp:newDate().toISOString()}},null,2)}finally{debugging.valuefalse}}调试 Tab 让原型活了起来——客户在演示现场点一下 Send800ms 后看到一段真实的 JSON 响应比这里应该会返回数据有说服力得多。6.3 返回按钮 面包屑返回按钮用router.back()或router.push(/api-manage/registry)。面包屑的第二项带了path点击能跳回列表页。七、注册弹窗新增/编辑复用同一个新增和编辑的表单字段完全一样——区别只是编辑时表单预填了数据。所以用一个弹窗组件通过mode区分!-- 在 ApiRegistry.vue 中 -- AppDialog v-modeldialogVisible :titledialogMode create ? 新增 API : 编辑 API :loadingsubmitting confirmhandleSubmit el-form refformRef :modelform :rulesrules label-width100px el-form-item labelAPI 名称 propname el-input v-modelform.name placeholder请输入 API 名称 / /el-form-item el-form-item label协议 propprotocol el-select v-modelform.protocol stylewidth: 100% el-option labelHTTP valueHTTP / el-option labelHTTPS valueHTTPS / el-option labelgRPC valuegRPC / /el-select /el-form-item el-form-item label接口地址 propurl el-input v-modelform.url placeholderhttps://... / /el-form-item el-form-item label请求方式 propmethod el-select v-modelform.method stylewidth: 100% el-option labelGET valueGET / el-option labelPOST valuePOST / el-option labelPUT valuePUT / /el-select /el-form-item el-form-item label描述 el-input v-modelform.description typetextarea :rows3 / /el-form-item /el-form /AppDialogconstdialogVisibleref(false)constdialogModeref(create)constformRefref()constsubmittingref(false)constformreactive({id:null,name:,protocol:HTTP,url:,method:GET,description:})construles{name:[{required:true,message:请输入 API 名称,trigger:blur}],protocol:[{required:true,message:请选择协议,trigger:change}],url:[{required:true,message:请输入接口地址,trigger:blur}],method:[{required:true,message:请选择请求方式,trigger:change}]}functionopenCreate(){dialogMode.valuecreateresetForm()dialogVisible.valuetrue}functionopenEdit(row){dialogMode.valueeditObject.assign(form,row)dialogVisible.valuetrue}functionresetForm(){form.idnullform.nameform.protocolHTTPform.urlform.methodGETform.description}asyncfunctionhandleSubmit(){awaitformRef.value.validate()submitting.valuetruetry{if(dialogMode.valuecreate){awaitcreateApi(form)ElMessage.success(新增成功)}else{awaitupdateApi(form)ElMessage.success(编辑成功)}dialogVisible.valuefalsefetchData()}finally{submitting.valuefalse}}7.1 必填校验rules对象定义了每个字段的校验规则。formRef.value.validate()在提交前触发校验不通过则不会发请求。这是 Element Plus 表单的标准用法但值得强调——所有用户输入都必须校验原型也不例外。客户演示时填了个空值点提交如果没校验直接报错比提示请填写尴尬得多。7.2 提交 loading 成功提示提交时submitting trueAppDialog 的确认按钮自动进入 loading 态第 7 篇封装的:loadingprop。成功后ElMessage.success弹提示关闭弹窗重新拉列表。八、Mock 数据30 条真实感数据API 注册管理需要 30 条 Mock 数据。第 11 篇会详细讲 Mock 策略这里先给一个预览——数据要有血有肉名称协议URL状态管网泄漏检测接口HTTPShttps://api.pipe.com/leak-detect启用压力监测服务HTTPhttp://10.0.1.23:8080/pressure启用流量分析 APIgRPCgrpc://pipe-grpc/flow-analysis禁用水质预测模型HTTPShttps://api.pipe.com/water-quality启用…………每条数据的名称、URL、状态都有差异时间字段分布在最近 3 个月——这样列表页看起来像真实生产数据而不是测试数据 1/2/3。九、小结列表页范式API 注册管理模块做完我们沉淀出一个列表页范式筛选区下拉 搜索 ↓ 表格复选框 序号 字段列 操作列 ↓ 分页器30 条/页 ↓ 行操作详情/编辑/删除/调试 ↓ 弹窗新增/编辑复用 ↓ 详情页双 Tab基本信息 运行调试这个范式不是 API 注册管理独有的——模型汇聚、模型标准发布都是它的变体。区别只在于表格有哪些列“弹窗有哪些字段”“详情页有几个 Tab”。范式 不变的结构 可变的内容。把结构固化成通用组件AppTable、AppDialog把内容留给每个业务页面填——这就是企业级后台开发效率的秘诀。上一篇07 - 通用组件分页器、表格、对话框的封装下一篇预告列表页范式跑通了下一个模块模型汇聚是项目最复杂的——详情页有 3 个 TabTab 切换还要同步 URL。怎么让多 Tab 详情页不丢数据

相关新闻

Python爬虫实战:从4399小游戏网站入门数据采集

Python爬虫实战:从4399小游戏网站入门数据采集

1. 项目概述:从“玩”到“学”的爬虫实战 每次看到“4399小游戏”这几个字,是不是瞬间就感觉回到了那个偷偷在电脑课上打开浏览器,争分夺秒玩一局《狂扁小朋友》或《森林冰火人》的童年?这个网站承载了太多人的记忆,它…

2026/10/14 1:10:53 阅读更多 →
AI Agent开发盲区:从Anthropic连接故障看Harness层的重要性与实现

AI Agent开发盲区:从Anthropic连接故障看Harness层的重要性与实现

1. 项目概述:从一次“低级错误”看AI Agent的“阿喀琉斯之踵”最近,AI圈子里发生了一件挺有意思的事儿。Anthropic,就是那个开发了Claude的大模型公司,被曝出了一个所谓的“低级错误”。具体细节可能众说纷纭,但核心指…

2026/10/10 5:12:54 阅读更多 →
网盘直链下载助手深度解析:技术原理与高效下载解决方案

网盘直链下载助手深度解析:技术原理与高效下载解决方案

网盘直链下载助手深度解析:技术原理与高效下载解决方案 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼…

2026/10/10 14:18:52 阅读更多 →

最新新闻

GAN演进之路:从原始博弈到StyleGAN的生成对抗实践

GAN演进之路:从原始博弈到StyleGAN的生成对抗实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 1:10:05 阅读更多 →
电动汽车性能开发目标模板解析与应用

电动汽车性能开发目标模板解析与应用

1. 项目概述:电动汽车性能开发的导航图在电动汽车研发领域,性能目标设定就像建筑师的蓝图,直接决定了整车开发的方向和边界。这份Ford性能目标模板的独特价值在于,它将传统汽车巨头数十年的整车集成经验与电动化特性深度融合&…

2026/10/14 1:10:05 阅读更多 →
公开课回顾|提示词自我迭代进化:从静态 Prompt 到可进化系统

公开课回顾|提示词自我迭代进化:从静态 Prompt 到可进化系统

本次公开课的核心主题是“提示词自我迭代进化”。虽然课程最后还有一个演示没有完全跑完,但整体方法论已经讲清楚:重点不是一次写出完美提示词,而是让提示词在训练、评估、反馈中不断更新,最终形成可迭代、可回归、可版本化的提示…

2026/10/14 1:10:05 阅读更多 →
strchr函数误用与CTF实战:从qwb2019_one看指针返回值陷阱

strchr函数误用与CTF实战:从qwb2019_one看指针返回值陷阱

1. 从一道CTF题看strchr的真实行为1.1 这道题到底在考什么qwb2019_one 这道题,我第一次看到的时候觉得挺简单——不就是个字符串处理吗?结果上手之后才发现,坑全在strchr这个函数的返回值判断上。题目本身逻辑不复杂,给了你一段输…

2026/10/14 1:10:05 阅读更多 →
SAP S/4HANA采购主数据与货源确定实战避坑指南

SAP S/4HANA采购主数据与货源确定实战避坑指南

简介:本资源是SAP S4 HANA采购模块(S4520)的官方级中文教程PDF,专为应用顾问、项目经理及企业最终用户设计,系统解决SAP S/4HANA环境下端到端采购业务落地难题。内容覆盖采购主数据维护(含物料主记录视图分…

2026/10/14 1:10:05 阅读更多 →
八字排盘四千年:节气计算与儒略日工程实践

八字排盘四千年:节气计算与儒略日工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 1:09:04 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →