☰
AI写页面崩溃后,我用业务区块体系3周交付40页
2026/10/31 12:33:03 网站建设 项目流程

1. 一个月AI写页面的真实体验:从兴奋到崩溃

1.1 为什么我会走上“让AI写页面”这条路

先说背景。我手上有一个中后台管理系统要交付,大概四十多个页面,包含表单、表格、图表、权限配置、流程审批这些典型模块。团队就两个人,排期给了六周。按传统手写的方式,光是搭页面骨架、调样式、对接接口,保守估计要十周以上。于是我很自然地想到了用AI来加速——毕竟那段时间各种AI编程工具的宣传铺天盖地,说什么“一句话生成一个页面”“效率提升十倍”。

我当时的做法很朴素:把每个页面的需求写成Prompt,丢给AI,让它输出完整的页面代码,然后我复制到项目里跑起来,再手动修bug。第一个页面确实惊艳到我了,一个带搜索栏、分页表格、新增编辑弹窗的页面,AI在三十秒内生成了两百多行代码,跑起来居然能用。那一刻我真的觉得,前端要变天了。

但接下来一个月,事情开始往我没想到的方向滑。

1.2 前两周的蜜月期与隐藏的债务

前两周我大概生成了十五个页面,速度确实快。但问题在于,每个页面都是AI“独立”生成的。什么意思呢?就是页面A的表格用了自己的一套样式类名,页面B的按钮组件是另一套写法,页面C的弹窗又是第三种实现。单看每个页面都能跑,但放在一起,就像十五个人各穿各的衣服站在同一个舞台上,风格完全不统一。

更麻烦的是重复代码。AI不知道我项目里已经有什么,它每次都是从零开始写。于是同一个“日期格式化”函数,在十五个页面里出现了十五遍,写法还略有不同。同一个“请求拦截”逻辑,被复制粘贴了十几次。代码体积膨胀得很快,构建时间从最初的十几秒涨到了将近一分钟。

我当时的心态是:先跑通再说,后面统一重构。这个想法本身没错,但我低估了重构的代价。

1.3 第三周开始失控:样式冲突与逻辑打架

到了第三周,页面数量上到二十五个左右,问题集中爆发。最典型的是样式冲突。AI生成的页面里,有的用了全局样式覆盖,有的用了行内样式,有的用了CSS Module。当这些页面被路由切换加载时,全局样式互相污染,导致A页面正常、切到B页面后A的样式被改了。我花了整整两天时间排查一个“表格行高莫名变化”的问题,最后发现是另一个页面里一句全局的line-height设置。

逻辑打架也很要命。比如表单校验,AI在不同页面用了不同的校验库写法,有的用async-validator,有的自己写正则,有的依赖UI库自带的rules。当我把这些页面整合到一个项目里,校验提示的样式和时机完全不统一,测试同学提了一堆bug。

那段时间我每天的状态就是:早上打开项目,跑起来,发现昨天还好好的页面今天崩了,然后花半天找原因,发现是另一个页面的改动引起的。AI写页面的速度优势,被调试和修复的成本吃掉了大半。

1.4 第四周的崩溃:一个改不动也删不掉的页面

压垮我的最后一根稻草,是一个“用户权限配置”页面。这个页面逻辑比较复杂,有树形结构、穿梭框、批量操作。AI第一次生成的版本有bug,我让它改,它改了一版,引入了新bug;再改,又引入另一个。来回改了七八次之后,代码已经变成了一团乱麻——变量命名混乱、条件判断嵌套五六层、有些函数定义了但没调用、有些调用了但没定义。

我想手动重构这个页面,打开文件一看,六百多行,逻辑纠缠在一起,改一处动全身。我想删掉重写,又舍不得里面几个已经调通的接口逻辑。那个下午我盯着屏幕,第一次认真反思:让AI直接写页面,这条路是不是走错了?

问题不在于AI写得不好,而在于我把AI当成了一个“独立开发者”,让它自由发挥。而一个真实的前端团队之所以能高效协作,靠的不是每个人都很强,而是有一套共同的约束——组件库、规范、约定。AI缺的正是这个约束。

2. 转折点:我重新理解了“组件库”这三个字

2.1 传统组件库为什么救不了我

我一开始也想过用现成的组件库,比如市面上那些成熟的UI框架。但用下来发现两个问题。第一,这些库太“重”了,它们提供的是通用能力,而我的业务有大量特定场景,比如“带审批状态的表格”“可拖拽排序的权限树”,这些在通用库里没有,我还是得自己写。第二,通用库的样式风格和我司的设计规范对不上,改主题的成本很高,改完还容易在升级时出问题。

所以传统组件库解决的是“有没有基础组件”的问题,解决不了“业务页面怎么快速、统一地搭出来”的问题。我需要的不是一堆按钮和输入框,而是一套能让我和AI都遵循的“页面搭建规则”。

2.2 “不像组件库的组件库”到底长什么样

后来我调整了思路。我不再让AI直接写完整页面,而是先花时间做了一件事:把项目里高频出现的页面模式抽象出来,做成一套“业务区块”。这套东西我后来管它叫“不像组件库的组件库”,因为它不是传统意义上那种提供Button、Input的库,而是一套“页面级”的积木。

具体来说,它包含三层。第一层是基础组件层,这层我直接用了成熟的UI库,不重复造轮子。第二层是业务区块层,这是核心,比如“标准列表页区块”“标准表单页区块”“详情展示区块”“审批流区块”,每个区块把布局、交互、数据请求的骨架都封装好了,只留出配置项。第三层是页面模板层,针对最常见的几种页面类型,提供开箱即用的模板,复制过来改配置就能用。

这套东西的关键在于:它规定了“一个页面应该长什么样、由哪些部分组成、数据怎么流动”。有了这个规定,AI的角色就从“自由开发者”变成了“填空者”——它只需要根据我的需求,往区块里填配置和业务逻辑,而不是从零设计整个页面结构。

2.3 为什么这套思路能同时约束人和AI

这套思路之所以有效,是因为它把“创意”和“规范”分开了。页面的整体结构、样式风格、交互模式,这些需要统一的部分,被固化在区块里,人和AI都不能随意改。而具体的业务字段、接口地址、特殊逻辑,这些需要灵活的部分,通过配置和插槽暴露出来,人和AI都可以填。

对AI来说,它的任务变简单了:不用再考虑“这个页面该怎么布局”“按钮放左边还是右边”“表格要不要加边框”,这些区块已经决定了。它只需要理解业务需求,然后输出符合区块配置规范的代码。生成结果的稳定性大幅提升,因为变量少了。

对我来说,维护成本也降下来了。因为所有页面都基于同一套区块,改一个区块的样式,所有用到它的页面一起变。新增页面时,我也不用从零写,复制一个模板改配置就行。AI生成的代码,因为遵循了区块规范,和手写代码的风格是一致的,整合起来没有障碍。

3. 这套“业务区块”体系的具体设计与实现

3.1 区块的划分原则:按“页面意图”而不是“技术类型”

划分区块时,我踩过一个坑。一开始我按技术类型划分,比如“表格区块”“表单区块”“图表区块”。结果发现不好用,因为一个真实页面往往是多种技术类型的组合,比如一个页面上面是表单、下面是表格。按技术类型划分,组合起来还是很麻烦。

后来我改成按“页面意图”划分。什么叫页面意图?就是这个页面是干什么的。比如“列表管理页”的意图是展示一批数据并支持增删改查;“表单提交页”的意图是收集用户输入并提交;“详情展示页”的意图是只读地展示一条数据的完整信息;“审批处理页”的意图是展示流程状态并支持审批操作。

按意图划分的好处是,每个区块对应一类完整的页面场景,内部已经把布局、交互、数据流都编排好了。用的时候直接选对应的区块,而不是自己拼装。我最终沉淀了八个核心区块,覆盖了项目里百分之八十五的页面场景。

3.2 区块的接口设计:配置项、插槽与事件

每个区块对外暴露三样东西:配置项、插槽、事件。配置项用来描述这个页面的静态特征,比如标题、字段列表、接口地址、权限码。插槽用来插入自定义内容,比如某个特殊字段的渲染方式、额外的操作按钮。事件用来处理交互回调,比如提交成功后的跳转、删除前的二次确认。

以“标准列表页区块”为例,它的配置项大概长这样:title(页面标题)、api(列表接口)、columns(列定义)、searchFields(搜索字段)、actions(行操作)。插槽有toolbar(工具栏扩展)、column-xxx(某列的自定义渲染)。事件有on-create、on-edit、on-delete、on-refresh。

这套接口设计的关键是“约定大于配置”。大部分情况下,我只填配置项就够了,区块会自动处理好搜索、分页、加载状态、空状态、错误提示。只有遇到特殊需求时,才用插槽和事件去扩展。这样既保证了统一性,又保留了灵活性。

3.3 让AI理解区块:Prompt的结构化改造

有了区块体系之后,我给AI的Prompt也做了彻底改造。以前我的Prompt是“帮我写一个用户管理页面,要有搜索、表格、分页、新增、编辑、删除”。现在我的Prompt变成了结构化的,包含三部分:区块选择、配置填充、特殊说明。

具体格式是这样的。第一部分声明用哪个区块,比如“使用标准列表页区块”。第二部分给出配置项,用JSON格式列出title、api、columns等。第三部分说明特殊需求,比如“状态列需要用标签展示,不同状态不同颜色”“操作列除了编辑删除,还要加一个导出按钮”。

这样改完之后,AI生成的结果质量有了质的飞跃。因为它不再需要猜测页面结构,只需要按照区块的规范填充内容。生成出来的代码,和手写代码几乎无法区分,整合时零冲突。而且因为配置项是结构化的,我甚至可以写脚本批量生成页面,AI只负责处理那些需要理解业务逻辑的部分。

3.4 一个真实区块的代码骨架

为了让你有直观感受,我贴一个简化版的“标准列表页区块”骨架。注意这是示意,实际项目里会更复杂,但核心结构就是这样。

// StandardListBlock.jsx import { useTable, useSearch, useModal } from './hooks'; export default function StandardListBlock({ title, api, columns, searchFields, actions, slots = {}, onEvents = {}, }) { const { data, loading, pagination, refresh, handleSearch } = useTable({ api }); const { modalVisible, modalType, currentRecord, openModal, closeModal } = useModal(); return ( <div className="standard-list-block"> <div className="block-header"> <h2>{title}</h2> <div className="block-toolbar"> {slots.toolbar} <button onClick={() => openModal('create')}>新增</button> </div> </div> <SearchForm fields={searchFields} onSearch={handleSearch} /> <DataTable columns={columns} data={data} loading={loading} pagination={pagination} actions={actions} onAction={(type, record) => { if (type === 'edit') openModal('edit', record); if (type === 'delete') onEvents.onDelete?.(record); }} slots={slots} /> <EditModal visible={modalVisible} type={modalType} record={currentRecord} onClose={closeModal} onSuccess={() => { closeModal(); refresh(); }} /> </div> ); }

这个骨架里,useTable、useSearch、useModal是三个自定义Hook,分别封装了列表数据请求、搜索逻辑、弹窗状态管理。这些Hook是区块体系的基础设施,所有区块共用。AI在生成页面时,只需要关心传什么配置,不需要关心这些Hook怎么实现。

4. 实操:如何从零搭建属于你的业务区块体系

4.1 第一步:盘点你的页面,找出高频模式

搭建区块体系的第一步不是写代码,而是盘点。把你项目里所有的页面列出来,然后归类。我当时列了四十多个页面,归类后发现,列表管理类占了将近一半,表单提交类占了四分之一,详情展示类占了六分之一,剩下的是一些特殊页面。

这个盘点结果直接决定了我要做哪些区块。列表管理类最多,所以“标准列表页区块”要优先做,而且要做得很完善。表单提交类次之,所以“标准表单页区块”是第二个重点。详情展示类相对简单,可以稍后做。特殊页面不强行抽象,遇到时单独处理。

盘点的另一个目的是找出“变化点”。比如列表页里,哪些部分是固定的(搜索栏、表格、分页),哪些是变化的(列定义、搜索字段、行操作)。固定的部分封装进区块,变化的部分做成配置项。这样区块才能既统一又灵活。

4.2 第二步:定义区块的“契约”

盘点完之后,开始定义每个区块的契约。契约就是这个区块对外承诺的接口:你给我什么,我还你什么。定义契约时要想清楚三件事:哪些是必填的,哪些是可选的,哪些是通过插槽扩展的。

以“标准表单页区块”为例,必填的配置项有title、fields(字段定义)、submitApi(提交接口)。可选的配置项有initialValues(初始值)、layout(布局方式,默认两列)、labelWidth(标签宽度)。插槽有footer(底部按钮区扩展)、field-xxx(某字段的自定义渲染)。事件有onSubmitSuccess、onSubmitError。

定义契约时有个原则:能通过配置解决的,不要用插槽;能用插槽解决的,不要用事件。因为配置最简单,插槽次之,事件最复杂。尽量让使用者用最简单的方式完成任务。比如字段的校验规则,能通过配置项rules解决,就不要让使用者去写自定义校验函数。

4.3 第三步:实现区块并沉淀Hook

契约定义好之后,开始实现。实现时我建议先写Hook,再写组件。因为区块的逻辑复杂度主要在数据流和状态管理上,把这些抽成Hook,组件本身就会很薄,容易维护。

我项目里沉淀了大概十个核心Hook,比如useTable(列表数据)、useForm(表单数据)、useModal(弹窗状态)、useDetail(详情数据)、usePermission(权限判断)、useDict(字典数据)。这些Hook是区块体系的基石,它们把常见的业务逻辑封装好了,区块组件只是把这些Hook组合起来,加上布局和样式。

写Hook时要注意一点:Hook的入参和返回值要稳定。因为区块组件会依赖这些Hook,如果Hook的接口经常变,区块就得跟着改。所以设计Hook接口时要多想一步,考虑未来可能的扩展。比如useTable的返回值里,除了data、loading、pagination,我还预留了selectedRows、setSelectedRows,虽然一开始用不到,但后面做批量操作时就用上了。

4.4 第四步:用AI生成页面,验证区块体系

区块体系搭好之后,就可以让AI基于它生成页面了。这时的Prompt和之前完全不同。以前是描述需求让AI自由发挥,现在是告诉AI用哪个区块、填什么配置。

我通常这样写Prompt:“使用标准列表页区块,生成一个用户管理页面。配置如下:title为‘用户管理’,api为‘/api/users’,columns包含姓名、手机号、状态、创建时间,searchFields包含姓名、手机号,actions包含编辑和删除。状态列需要用标签展示,启用为绿色,禁用为灰色。”

AI拿到这样的Prompt,生成的结果非常稳定。因为它不需要设计页面结构,只需要把配置翻译成代码。生成出来的页面,和手写的区块用法完全一致,直接就能跑。我实测下来,一个标准列表页,从写Prompt到页面跑通,大概五分钟。而且因为遵循了区块规范,不会引入样式冲突和逻辑打架。

4.5 第五步:持续迭代,把新场景沉淀成新区块

区块体系不是一次做完就完了,它需要持续迭代。每次遇到一个新页面,如果发现它和已有区块相似但有差异,我会先想:这个差异是可以通过配置项和插槽解决的,还是需要新建一个区块?

如果差异很小,比如只是多了一个特殊字段,那就用插槽解决,不新建区块。如果差异较大,比如整个页面的交互模式都不同,那就考虑新建区块。新建区块时,尽量复用已有的Hook和基础组件,避免重复造轮子。

我项目里从最初的三个区块,慢慢迭代到了八个。每新增一个区块,都是在实际项目中遇到了真实需求,而不是凭空设计的。这样沉淀下来的区块,才是真正有用的。

5. 踩过的坑与排查技巧实录

5.1 区块粒度太细或太粗都会出问题

区块粒度是个需要反复调整的东西。我一开始把区块做得太细,比如“搜索栏区块”“表格区块”“分页区块”分开做。结果用的时候还是要自己拼装,和不用区块差不多。后来我又把区块做得太粗,一个区块包打天下,结果配置项多到几十个,比手写还复杂。

最后我找到的平衡点是:一个区块对应一类完整的页面场景。比如“标准列表页”就是一个完整场景,它内部包含了搜索、表格、分页、弹窗,对外只暴露必要的配置。这样使用者选一个区块就能完成一个页面,不需要拼装。而区块内部的细节,使用者不用关心。

判断粒度是否合适,有个简单标准:如果一个区块的配置项超过十五个,说明它管得太多了,应该拆分;如果一个区块用的时候还需要使用者自己拼装其他组件,说明它管得太少了,应该合并。

5.2 AI生成的代码不符合区块规范怎么办

即使有了区块体系,AI偶尔还是会“自由发挥”。比如我让它用标准列表页区块,它却在里面自己写了一个表格,没用区块内置的表格。遇到这种情况,我的处理方式是:先检查Prompt是否足够明确,如果Prompt里已经说清楚了用哪个区块,AI还是跑偏,那就是AI对区块规范的理解不够。

解决办法有两个。一是在Prompt里附上区块的接口文档,让AI明确知道这个区块接受哪些配置、有哪些插槽。二是在项目里加一层校验,比如用ESLint规则禁止在页面里直接引入基础表格组件,强制使用区块。我两个都用了,效果很好。加了校验之后,AI生成的代码如果不符合规范,构建时就会报错,我立刻就能发现并让它重写。

5.3 区块升级时如何不破坏已有页面

区块体系用久了,难免要升级。比如某个区块的样式要调整,或者某个Hook的逻辑要优化。升级时最大的风险是破坏已有页面。我踩过一次坑:优化了useTable的分页逻辑,结果所有用到的页面分页都乱了。

后来我定了个规矩:区块的对外接口只增不改。也就是说,配置项可以新增,但不能删除或改变含义;插槽可以新增,但不能改变已有插槽的语义;事件可以新增,但不能改变已有事件的触发时机。如果确实需要做破坏性变更,就新建一个区块版本,比如StandardListBlockV2,让新页面用新版本,老页面继续用老版本,慢慢迁移。

这个规矩听起来保守,但实际用下来很稳。因为区块是基础设施,基础设施的稳定性比先进性重要。宁可多一个版本,也不要让已有页面出问题。

5.4 常见问题速查表

问题现象可能原因排查思路解决方法
AI生成的页面样式和项目不一致AI没用区块,自己写了样式检查生成代码是否引入了区块在Prompt中明确区块名称,加ESLint校验
页面切换后样式错乱全局样式污染检查是否有页面写了全局样式禁止在页面中写全局样式,统一用区块样式
区块配置项太多,用起来复杂区块粒度过粗统计配置项数量,超过15个考虑拆分按页面意图拆分成多个区块
区块升级后老页面报错破坏了对外接口对比升级前后的接口差异遵循“只增不改”原则,破坏性变更新建版本
AI生成的代码跑不起来Prompt信息不足或矛盾检查Prompt是否包含区块名、配置项、特殊说明结构化Prompt,分三部分写清楚
多个页面重复请求字典数据没有缓存机制检查字典Hook是否有缓存在useDict中加内存缓存,相同字典只请求一次

5.5 几个让我省下大量时间的实操心得

第一个心得:先写三个页面,再抽象区块。不要一上来就设计区块,那样容易设计出用不上的东西。先手写两三个同类页面,找到共同点,再抽象。我项目里的区块,都是先手写了至少两个页面之后才抽象出来的,这样抽象出来的区块才接地气。

第二个心得:区块的文档和示例比代码本身更重要。因为区块是给人和AI共用的,文档写不清楚,AI就理解不了,人也不愿意用。我给每个区块都写了三样东西:接口文档(配置项、插槽、事件)、示例代码(一个最简用法)、常见场景(三五个典型配置)。这三样东西写好了,用起来效率翻倍。

第三个心得:让AI参与区块的维护。区块本身也是代码,也会需要修改。我有时候会让AI帮我改区块,比如“给标准列表页区块加一个导出按钮的插槽”。因为区块的代码结构很规整,AI改起来比改业务页面准确得多。改完之后我review一下,没问题就合并。这样区块体系自己也在进化。

第四个心得:不要追求一步到位。我一开始想设计一套完美的区块体系,覆盖所有场景。结果发现根本做不到,因为业务在变。后来我改成“够用就好,持续迭代”,先覆盖百分之八十的场景,剩下的遇到再说。这样反而推进得更快,而且因为每个区块都是被真实需求驱动的,没有一个是多余的。

6. 这套方法带来的实际变化与后续扩展方向

6.1 效率数据:从六周排期到三周交付

用了区块体系之后,那个原本排期六周的项目,实际三周就交付了。具体来说,四十多个页面里,三十多个是基于区块生成的,每个页面平均耗时从半天降到了两小时以内。剩下的特殊页面,因为有了区块体系的基础设施(Hook、基础组件),手写起来也快了很多。

更重要的是返工率大幅下降。之前AI自由生成的页面,大概有三分之一需要大改。用了区块之后,需要大改的不到十分之一。因为区块已经把常见的坑填平了,AI生成的结果基本都在预期之内。

6.2 代码质量:从各自为政到整齐划一

代码质量的变化也很明显。之前每个页面风格不同,代码审查时很难统一标准。现在所有页面都基于同一套区块,代码结构高度一致,审查起来很快。新人接手项目时,只要理解了区块体系,就能看懂所有页面。

构建体积也降下来了。因为重复代码被区块和Hook吸收了,项目体积比之前小了将近四成。构建时间从一分钟回到了二十秒左右。这些收益是当初让AI自由写页面时完全没想到的。

6.3 后续扩展:把区块体系接入更智能的工作流

现在我在尝试把区块体系和更智能的工作流结合。比如,我在探索用MCP协议把区块的接口文档暴露给AI工具,这样AI在生成代码时可以直接读取区块的最新定义,不需要我在Prompt里重复描述。我也在尝试让AI根据需求文档自动选择区块、生成配置,进一步降低人工介入。

另一个方向是把区块体系和设计稿打通。如果设计稿能自动解析成区块配置,那从设计到页面的链路就完全自动化了。这个还在探索阶段,但方向是清晰的。

6.4 给同样在AI写页面路上挣扎的朋友几句实在话

如果你现在也在用AI写页面,而且遇到了和我类似的问题,我的建议是:先停下来,别急着让AI写更多页面。花两天时间,把你已经生成的页面盘点一下,找出重复的模式,抽象成区块。这两天的时间投入,会在后面几十个页面里加倍还回来。

不要指望AI能理解你项目的全部上下文,它做不到。你能做的,是把项目的上下文固化成区块和规范,让AI在一个受约束的环境里工作。约束不是限制AI的能力,而是让它的能力用在正确的地方。

最后,区块体系不是银弹,它解决的是“页面搭建的标准化和效率”问题。如果你的项目页面很少,或者每个页面都高度定制,那可能不需要区块。但如果你的项目有大量同类页面,而且你在用AI辅助开发,那这套思路值得一试。我踩过的坑,你可以不用再踩一遍。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询