普通视图
# Vue 中 provide/inject 与 props/emit 的对比与选择
Vue 中 provide/inject 与传统状态管理的深度对比
大厂面试:与HTML相关的基础知识点解析
译:自由实验你的代码—Git worktree
ts极速封装axios,关注点分离,包会、包爽!
Cesium基础(四):部署离线地图和地形资源
npm link本地测试React组件库报错“Invalid hook call”?从多实例到pnpm依赖的完整排查指南
Koa2 跨域实战:`withCredentials`场景下响应头配置全解析
React 闭包陷阱攻防:函数式编程思想的应用
大学生常用-原生js实现:点击切换图片,轮播图,tab切换,分页符,秒杀等等......直接copy就能使
JS进阶-异步编程、跨域、懒加载
Agentic Loop与MCP:大模型能力扩展技术解析
Flutter中的Key详解
你以为你很忙,其实你只是在拼命挖坑
许多开发者提出过真实担忧:
“我封装做得太好,结果每次产品一改就要改我写的组件,反而更累,更危险。”
🧠 一种隐形的勤奋:封装≠高效,反而可能在制造“维护地狱”
许多开发者以为,封装做得多、抽象做得早,就等于“技术含量高”。但你有没有想过:
你以为你在筑高楼,其实你在加速挖坑。
当你的封装方案:
- 抽象了一堆“可能用到”的场景;
- 把逻辑硬塞进组件内部;
- 每次业务一变,就得拆自己造的轮子;
你封装的,不是系统能力,而是系统负担。
我们来理性分析这个现象:
✅ 封装不是目标,而是提升系统能力的手段
很多“被封装害惨”的例子,其实是封装时闭门造车、抽象过度:
- 把所有逻辑塞进一个巨型组件
- 写死流程,缺乏可配置点
- 不留扩展口,导致每次改动都要大拆大建
这类封装,其实是耦合增强,不是复用增强。
✅ 真正的好封装:以业务为中心、支持变化、渐进抽象
- 职责单一:组件小而精,单一职责更易复用
- 扩展性强:留好 slots、hooks、配置项,支持被覆盖和组合
- 业务驱动:先实现真实场景,再抽象共性;不要一开始就封装一堆“未来可能用到的功能”
✅ 封装能力 = 抽象能力 + 协作能力
封装不是“你写了一堆组件”,而是你能:
- 拆解问题,抽象共性方案
- 组织配置,服务多场景
- 兼顾协同,推动团队对齐
封装不仅是代码能力,更是系统思维 + 协作能力 + 业务理解力的体现。
✅ 封装 ≠ 危险,盲封装才危险
被裁掉的从来不是“能封装的那个人”,而是“封得死、改得痛、协作差”的人。 真正的高级工程师,写的不是组件,是系统能力;堆的不是代码,是组织效率。
搜索区域设计进化
列表页的搜索框相当于“筛选引擎”,但往往会有很多条件,让用户一眼都找不到重点。初级阶段,我们习惯每个页面都手写一堆 <Input>
、<Select>
,校验逻辑也各自写一套,结果不同页面的搜索区几乎同质化。进阶思路是:把表单和字段配置化、动态化。比如封装一个通用的 SearchForm
组件,只要传入字段配置数组(label、字段名、类型、选项等),表单就能自动生成。再进一步,可以采用 JSON Schema 驱动(或类似 Formily 这样的方案)来定义搜索表单,也就是让数据来驱动界面。利用 Schema,我们只需关注“有哪些字段、要怎么校验”,而让表单组件自动渲染对应的输入项。最后可以将字段信息放到一个中心(Field Center)管理:统一字段的标签、数据源和校验规则,这样修改一次,所有页面都能同步生效。这样的演进往往会带来惊喜——当项目A和项目B都需要一个“日期区间”字段时,我们只需在字段中心配置,而不用再抄一遍代码。
- 抽象表单组件:将常用的表单渲染成可复用组件,只在配置里声明字段属性。
- Schema 驱动表单:使用 JSON Schema 规范来描述表单(例如 Formily),前端根据 Schema 自动生成 UI。
- 字段中心(Field Center) :集中管理所有字段的 label、组件类型、校验规则等。任何变更都只需在配置里改一次,避免四处改动。
这样做后,搜索区从冗杂的代码堆砌变成了参数化配置。记得有次项目中,有十多个列表页需要几乎相同的搜索字段,以前改一个字段就要逐页修改,现在只改字段中心的一个 JSON 配置文件,就完成了所有联动,效率飞跃。🎉
表格区域抽象
表格区域是中后台的核心展示。但在细节上,很多需求都差不多:列(columns) 、格式化、状态映射 等工作高度重复。比如上一个项目写好的状态列,我们在下个项目可能又写了一遍,或是在导出等功能里踩坑。进阶思考是:建立一个通用的表格配置机制。我们可以将列的定义抽象出来,类似列数组的配置对象,并在多个页面间复用。例如:[ { title: '名称', dataIndex: 'name' }, { title: '创建时间', dataIndex: 'createdAt', render: formatDate } ]
这样的配置可以放到共用文件里,不同页面只需要引用即可。对一些复杂字段,再配合数据字典做映射,将后台返回的状态码、性别码等自动渲染为可读文字(比如 {'M': '男', 'F': '女'}
),避免在每个 render 里 switch
或 if
。如果有权限需求,还可以在列配置中加上 requiredRole
或 show: checkPermission(...)
,让表格自动根据用户角色隐藏列或操作按钮。
-
统一列配置:将 Table 的
columns
数组封装成可复用配置文件或函数,不同列表页共用相同列名、类型等定义。 -
格式化统一:比如日期、货币、百分比等统一使用工具函数,甚至在列配置里就设置好
render: formatDate
,整个项目中保证风格一致。 - 权限/字典映射:在列定义中声明数据字典和权限要求,让组件自动根据字典表(如状态、枚举)渲染标签,以及根据权限动态控制显隐。
例如在一个项目中,我们有多个表都需要“状态”这一列,以前代码里每个页面都写一段 switch
逻辑。后来我们把所有状态码和含义写进一个字典模块,表格渲染时统一调用,让状态列直接用 <StatusBadge status={record.status} />
来渲染,省了不少重复代码。正如业界所说,很多组件库(如 AntD ProTable)已内置分页和筛选逻辑,但对于自定义场景,我们需要自己定义表格行为。总之,把表格想象成一组组件的集合,每个组件(列)都应该职责单一,只做自己的事,不用每页重复造轮子。
编辑与跳转抽象
中后台列表页通常还会有“新增/编辑”功能:用户点一条记录可以跳转到详情或弹窗编辑。刚开始,很多团队都是每个页面再抄一套跳转逻辑:例如在 Vue 里写死路由路径、带上 ID,然后在详情页里写条件逻辑区分「新增还是编辑」。进阶思维是把页面行为模式化,统一状态驱动。一个常见做法是:定义好路由 schema,比如 /users/list
、/users/form/:mode(add|edit)/:id?
,然后写一个通用的 表单页组件,它根据 URL 中的 mode
参数决定是「创建态」还是「编辑态」。也可以统一使用对话框,当 mode
是 add
或 edit
时弹出一个 Modal;无论用何种呈现方式,数据流与界面分离才是一致思想。
- 状态驱动页面:用路由参数或页面变量明确「新增 / 编辑 / 详情」三种状态,组件只根据状态渲染不同的表单或接口调用。
-
弹窗 vs 页面:在可行时把逻辑抽离出来,用同一个组件支持两种模式——比如 props 传入
isModal
,控制以对话框或独立页面形式展示。 -
模式化接口调用:把「新增调用 POST,编辑调用 PUT」等网络请求逻辑放在统一的服务层,页面组件只调用相同的
saveItem(data)
接口,让后端根据 ID 自动区分新旧。
换句话说,我们让「去哪儿编辑」「以什么模式编辑」「如何保存」这些事情,都交给配置或统一的逻辑去管理,而不是散落在各个列表页里重复编写。这样,当我们决定把用户编辑表单从页面改成弹窗时,只改一处配置或组件;新增字段时,也只改表单配置,不用每个链路都瞎写一处。例如,在一次项目迭代中,我们给用户编辑新增了几行输入字段,最开始是加在弹窗页面和独立页面各写一遍,后来改用配置驱动后,字段自动体现在所有地方,开发效率和质量都上去了。
工程化提升维度
开发列表页不仅仅是写功能,更要从工程化角度思考:把样式、状态管理、权限、字段配置这些要素标准化。比如在样式层面,统一使用设计系统和主题,颜色、间距、字体等统一变量,避免各页面自定义一堆重复样式。状态管理上,可以定义一套固定的数据流方案:列表 loading、搜索条件、分页信息、刷新函数等都规范成约定好的写法(比如结合 Vuex/Redux 或者 Hooks),一行代码即可控制同事列表组件的刷新。权限层面,可以统一设计权限配置入口:例如一个 permissions.js
文件里定义所有页面和功能点的权限标识,每个组件只需引用该配置检查显隐。字段配置则可抽象成元数据,例如后端返回的 API 数据结构,在前端做成模型对象,保证字段名称一致,减少前端 hard code 字段出现 bug。
- 样式标准化:使用公共样式变量、主题包、组件库设计语言,让 UI 风格统一可维护。
- 状态管理规划:列表的分页、查询条件、选中项等状态都放入统一管理(Redux/Vuex 或 hooks 中),使不同页面结构一致。
-
权限统一处理:全局集中定义权限点和角色表,组件只要调用
hasPermission(key)
,无需自己分散实现复杂逻辑。 - 字段配置中心:将 API 字段定义、表单字段规则、字典映射等放到统一配置文件或系统中,字段增删改查一处变更即可。
这样的工程化提升,就是在为自己腾出更多时间做创新。记得在某项目中,我们把表格分页器、导出按钮、全选逻辑封装进了一个基础组件,后来只在该组件上设置 showExport=true
就能应用到所有表格,项目后期新增需求时几乎不用写重复代码。透过这层认知跃迁,你会觉得自己从“搬运工”向“系统工程师”进化了一步:不再只是重复敲键盘,而是设计规则、制定流程,把“机械活”交给机器去做。
开发行为的进阶思维
做开发不只是机械地配合需求,更要主动思考如何提高效率。不要只等着后端提供接口,再慢慢把页面一项项填上;可以尝试Mock 驱动开发:先画出 API 和数据的假样子,前后端并行推进,这样自己有更多空间探索最佳方案。比如接手新项目时,可以先用 Postman 或 MockServer 写一个数据结构,然后基于它封装列表页面原型,再随时调整;这样设计往往比等接口到位后再来补坑,节省很多来回。主动推进还体现在日常中:如果发现团队里有重复工作,如每次都要配置某个重复的工具,不妨拿出来讨论,引入一个通用解决方案。
- 主动驱动:从“被动接需求”变为“主动提方案”,培养前瞻性思维。问自己:有没有办法做成更通用的组件?有没有工具可以自动化?
- Mock 驱动设计:提前模拟接口和数据,先画雏形再完善细节。这样前端可以先行实现页面,后端更清楚需求。
- 跨团队协作:定期总结共性问题,共同推动设计规范。如与后端达成契约式开发(约定接口格式),与产品沟通前端可实现的快速方案。
比如我曾和团队一起,引入了低代码构建工具,让产品同学也能拖拉拽生成页面雏形,极大减少重复工作量。在这个过程中,开发者的思维从「这个功能怎么写」跃迁到「如何让更多人更快写出这个功能」。正如一句常挂在嘴边的话:授人以鱼不如授人以渔,我们要教自己和团队“钓鱼”而非仅仅拎鱼上钩。
识别并重构低水平重复劳动
如果你发现自己经常复制粘贴相似代码、调整几乎一样的界面、解决一模一样的问题,就说明可以进行 重构 了。这些低效重复劳动的例子很多:一个页面里做过的搜索、表格、导出逻辑,在下一个页面往往又从零开始;或者写接口时又忘记处理分页参数,手工补了一遍。好的做法是:举一反三,把共用逻辑提炼成工具函数、公共组件或通用页面配置。
- 辨别重复点:留意每天敲的键盘里有哪些是“搬砖”,列个清单(例如:每个列表都写一遍分页逻辑、每个表单都写一份校验)。把它们画出来,你就知道要抽象什么。
-
重构封装:针对清单里的项目,逐个拆分成可复用的模块。比如做一个
useTable
Hook 包含分页和刷新逻辑;写一个通用导出功能只需要传入数据接口即可。 - 持续迭代:重构不是一次完成的。随着经验积累,会有新的重复点出现。比如之前没想到,现在发现条件列表都用下拉搜索效果不好,就统一写个封装组件,之后再也不用在不同页面重复那段逻辑。
关键是要勇于停下手头的「塑形任务」,抽时间搭梯子和开路。开始阶段可能感觉重构费劲(反正「搬砖」也能做完页面),但回头来看,每多写一个抽象,后面至少省几天。长期下来,你会庆幸当初迈出的这一步,因为它让你从简单地执行变成敏锐地整合资源,能力也就跟着飞跃了。
组件理解与职责边界
组件就像一个个乐高积木,每个积木都要只做一件事。组件的单一职责原则告诉我们:一个组件只负责一个功能点。例如,既然有了统一的SearchForm
组件,就不该在这个组件里写数据库请求,也不要混合太多业务逻辑;而是把数据获取留给上层容器组件来做。实践里,一个列表页通常会拆成“容器组件”和“展示组件”两层:**容器组件(页面级)**负责接口请求、状态管理等业务处理;展示组件只负责接收 props 渲染 UI,比如表格、表单、按钮等。把这两层分开好处很多——展示组件不关心业务,可以在多个场景复用;容器组件专注业务逻辑,也容易测试。
- 单一职责:遵循单一职责原则,每个组件只完成「定义好的那件事」。不要让一个组件同时管数据请求和多处 UI 布局,否则代码会纠结难以维护。
- 容器 vs 展示:将业务逻辑(数据获取、计算)放在容器/页面组件里,将视图渲染放在纯展示组件里。这样 UI 组件就可以“傻瓜式”接收数据,重用性更强。
- 接口简洁:组件通信使用明确的输入输出(props),尽量避免跨组件调用或全局状态的隐式依赖。这降低了耦合度,让组件更易于理解和测试。
可以想象:如果组件设计得像万能积木,要啥有啥,后期维护就跟炒杂碎一样乱。相反,每个组件就像乐高的标准块,只露出简单接口,才能像模块化积木那样灵活组合。随着经验丰富,你会发现能否正确划分组件边界常常决定了页面能否优雅地扩展和维护。优秀的组件划分,让你不必为小改动而翻遍整个代码库。
页面能力 vs 系统建设力
写好一个页面固然重要,但更大的进阶是提升整体开发效能的能力——也就是系统建设力。与其把时间都花在“造每辆车”,更应该考虑如何“造出造车的工厂”。前面所有模块的经验都是这一思想的体现:我们不只是写单页 CRUD,而是在构建适用于所有列表页的能力和规则。当团队的开发者都能轻松地调用现成组件、自动生成页面时,开发效率将成倍提升。
- 迁移心态:从“完成一个功能”转变为“建立一套方式” 。 每增加一个列表页之前,先问问:有没有机会把它变成模板或配置?如果大多数列表页都长得差不多,那么我们就该建设“列表页平台”,而不是重写第二个复制品。
- 工具与脚手架:思考能否做出页面生成器或 CLI 脚本。一些团队会自研脚手架:输入表名、字段配置,就能自动生成 React/Vue 页面骨架和接口代码。这样的工具投入产出比极高,能让新人快速上线新功能。
- 价值最大化:集中精力解决通用问题,而不是单例问题。如同前文提到的中后台场景占比高达 86%,我们就在这 86% 的场景上持续打磨,能让日后千篇一律的页面开发变得一次搞定。
页面能力 ≠ 项目交付能力
能写页面 ≠ 能撑住一个系统。还需要:
- 多模块协作(前后端联动,产品对齐)
- 权限、字段、模块抽象设计
- 异常兜底、流程控制能力
🧭 最后的总结:你以为你很忙,其实你在为过去的自己还债
你很忙,不代表你在成长。每天加班、应急、救火的你,可能是在为自己曾经草率写下的组件买单。
忙 ≠ 有价值。 不要被眼前的任务束缚住脚步。当别人在忙着搬砖时,你正在设计和优化搬砖的“机器”。每改进一个流程、统一一套规范,就是在积累“乘法效应”,让未来的开发工作变得越来越轻松。正如一句金句所说:“别只抬头看天花板,你要在天花板上打洞。”(意思是别满足于现状,去创造新可能。)通过以上各个方面的思维转变与实践提升,你的认知也会随之跃迁,对中后台开发的理解将从“简单 CRUD”变成“整体治理”,最终实现真正的技术升级与成长。🚀