Skip to content

页面拆解与 Prompt 策略 ​

先拆页面与组件契约,再写 Prompt——让 AI 一次生成对的前端代码。

AI CODING · 场景二 · 契约先行

顺序固定:主路径 → 页面职责 → 组件 props/事件 → 给 AI 的 Prompt → diff → 浏览器。跳过契约直接「写首页」,后面极难拆。

时间 40–60 分钟(拆卡)组件 2 个起输出 可执行 Prompt
开始拆 →
本节要点
  • 首页 / 详情各干什么、两个组件的输入输出
  • 一张「看见就停」的坏 Diff 样例
  • 组件+首页、详情页两张可粘贴 Prompt

跟做顺序 ​

text
主路径(用户点什么)
  → 页面清单(每页一句话职责)
  → 组件契约(props / 事件)
  → 域规则(筛选 / 查找)——场景二总览 Mock 已先做则跳过
  → 给 AI 的 Prompt(一次一个组件或一页)
  → 看 diff → 浏览器验收
前置 选型备忘已落、domain / data 已有 MealSceneId 与筛选函数。没有的话先回 场景二 · Mock。

页面清单 ​

页面职责不做
首页保存当前用餐场景;调 dishesForScene;组合选择器与列表;收 open 后导航声明第二套场景数组;在模板里手写 filter
详情从路由读 id;调 findDish;展示字段或空态复制整份 Mock;自己请求网络

用户点什么(和场景一同一条):

text
打开首页 → 选「一人食」→ 列表变化 → 点「番茄炒蛋」→ 详情有小贴士
故意坏 id → 空态,不是白屏

冻结两个组件契约 ​

text
ScenePicker
输入:scenes、modelValue
输出:update:modelValue(sceneId)

DishCard
输入:item
输出:open(dishId)

卡片不自己跳转;父页听事件再导航——以后列表复用到收藏页时不用改卡片。

TypeScript 形态示意:

ts
// ScenePicker
defineProps<{ scenes: readonly MealScene[]; modelValue: MealSceneId }>();
defineEmits<{ "update:modelValue": [value: MealSceneId] }>();

// DishCard
defineProps<{ item: Dish }>();
defineEmits<{ open: [id: string] }>();

首页接线形态(实现细节可调,职责不能漂):

ts
const selectedScene = ref<MealSceneId>("solo");
const visible = computed(() =>
  dishesForScene(DISHES, selectedScene.value),
);

function onOpen(id: string) {
  uni.navigateTo({ url: `/pages/detail/index?id=${id}` });
}

看见这种 Diff 就停 ​

diff
 <script setup lang="ts">
+const scenes = [
+  { id: "family", name: "家庭" },
+  { id: "future-scene", name: "未约定场景" },
+]
+const visible = computed(() =>
+  dishes.filter((item) => item.sceneIds.includes(selected.value)),
+)
+function open(id: string) {
+  uni.navigateTo({ url: `/pages/detail/index?id=${id}` })
+}
 </script>

三类问题叠在一起:组件新建场景真源、组件做筛选、组件决定 URL。
处理:场景与筛选回 domain,导航回 page;不要在页面加兼容分支「先顶着」。

坏信号正确落点
组件内再声明 scenes = [...]只用 props 传入的 MEAL_SCENES
组件内 filterdishesForScene
卡片里 navigateTo只 emit('open', id)
MealSceneId 改成 string打回,不要放宽

给 AI 的 Prompt ​

两张卡分开执行。第一组出错只查组件与首页;第二组只查路由与详情。

A · 两个组件 + 首页接线 ​

给 AI · Prompt · ScenePicker + DishCard + 首页
text
【目标】拆出用餐场景选择与菜品卡片,并接到首页。

【允许改】
- 创建 components/ScenePicker.vue
- 创建 components/DishCard.vue
- 修改 pages 首页

【禁止改】
- domain/、data/(若已存在)
- package.json、lockfile、构建配置
- Mock 字段结构

【契约】
- ScenePicker:scenes / modelValue → update:modelValue(MealSceneId)
- DishCard:item → open(dishId)
- 首页负责状态、调用 dishesForScene、导航

【验收】
- 开发预览:切换用餐场景列表变化;点卡片进详情(详情可下一张卡再做)
- 若有单测:domain 相关全绿

【请你】先复述允许文件、禁止文件与契约;我确认后再改。

B · 详情页(单独一张) ​

给 AI · Prompt · 详情页
text
【目标】补齐菜品详情页。

【允许改】详情页文件 + 路由注册(如 pages.json)

【禁止改】domain/、data/、components/、依赖配置

【契约】
- 从 onLoad/query 读 id;非 string 当空
- 使用 domain 的 findDish;不复制 Mock
- 合法 id:菜名、摘要、依据、小贴士;非法 id:明确空态文案

【验收】合法 id 与故意错误 id 各点一次;构建通过

【请你】先复述范围与契约,确认后再改。

Prompt 策略三条 ​

  1. 范围写死 — 允许 / 禁止文件列表
  2. 契约写死 — 输入输出比「好看」优先
  3. 验收写死 — 你点哪里算过;AI 自称完成不算

执行后看 diff:

bash
git diff -- components/ScenePicker.vue \
  components/DishCard.vue \
  pages/...

核对:props/事件是否被放宽成 string;是否出现第二套场景数组;导航是否漏在卡片里。

更多原则 → Prompt 工程。踩坑对照 → 避坑实录。

晨悦 AI 实践手册