sync: 新增 BMAD 开发流程重构 - 目录结构 modes/phases/rules + 新增自动修复引擎 + H5 不兼容组件替换方案
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# Uni-app 微信小程序平台参考
|
||||
|
||||
> **⛔ 主流程文件统一引用此文件**:所有 uni-app/微信小程序的平台特定内容集中于此。
|
||||
> 主流程文件(auto-fix/engine / iron-laws / journey-mode / visual-verification / validation-mode / e2e-testing / phase-03-implement)中不再内联平台特定方案,改为引用本文件对应章节。
|
||||
> 主流程文件(auto-fix-engine / iron-laws / journey-mode / visual-verification / validation-mode / e2e-testing / phase-03-implement)中不再内联平台特定方案,改为引用本文件对应章节。
|
||||
|
||||
---
|
||||
|
||||
@@ -397,131 +397,3 @@ onPullDownRefresh(() => {
|
||||
uni.stopPullDownRefresh(); // ← 新增
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. H5 不兼容组件替换方案(⛔ 强制)
|
||||
|
||||
### 问题
|
||||
|
||||
uni-app 原生组件(`<checkbox>`/`<radio>`/`<switch>`/`<slider>`/`<picker>` 等)在 H5 环境下可能出现:
|
||||
- 不渲染(DOM 中存在但宽高为 0)
|
||||
- 不可交互(点击无响应)
|
||||
- 样式异常(默认浏览器样式覆盖 Neon Pulse 设计)
|
||||
|
||||
微信小程序正常但 H5 不正常的组件,**不得标记为"环境限制"跳过**。必须用跨平台兼容的纯 view + CSS 方案替换。
|
||||
|
||||
### ⛔ 核心原则
|
||||
|
||||
- **禁止**使用 uni-app 原生表单组件(`<checkbox>`/`<radio>`/`<switch>`/`<slider>`/`<picker>`)
|
||||
- **必须**使用纯 `<view>` + CSS + `@tap` 实现等效功能
|
||||
- 这样做:小程序和 H5 都能正常渲染,无需任何平台判断
|
||||
|
||||
### 不兼容组件清单
|
||||
|
||||
| uni-app 原生组件 | H5 问题 | 替换方案 |
|
||||
|------------------|---------|---------|
|
||||
| `<checkbox>` | 不渲染或样式异常 | view + Iconify check 图标 |
|
||||
| `<radio>` | 不渲染或样式异常 | view + CSS 圆点 |
|
||||
| `<switch>` | 样式与设计系统冲突 | view + CSS 滑动开关 |
|
||||
| `<slider>` | 样式不可控 | view + CSS 进度条 + @touchmove |
|
||||
| `<picker>` | 原生弹窗与 H5 不兼容 | 自定义弹窗组件 |
|
||||
|
||||
### 检测方法(⛔ 旅程验证步骤级强制)
|
||||
|
||||
```bash
|
||||
# 扫描所有 .vue 文件中的原生表单组件
|
||||
grep -rn '<checkbox\|<radio\|<switch\|<slider\|<picker' app/mini-program/src/ --include="*.vue"
|
||||
# 发现任何匹配 → 触发 AUTO-FIX #23
|
||||
```
|
||||
|
||||
### 替换模板
|
||||
|
||||
#### checkbox → view + Iconify check
|
||||
|
||||
```vue
|
||||
<!-- 修复前: -->
|
||||
<checkbox :checked="agreed" @tap="agreed = !agreed" color="#ffb3b5" />
|
||||
|
||||
<!-- 修复后: -->
|
||||
<view class="custom-checkbox" :class="{ checked: agreed }" @tap="agreed = !agreed">
|
||||
<view v-if="agreed" class="i-lucide-check check-icon"></view>
|
||||
</view>
|
||||
```
|
||||
|
||||
```css
|
||||
.custom-checkbox {
|
||||
width: 18px; height: 18px; min-width: 18px;
|
||||
border-radius: 4px;
|
||||
border: 1.5px solid rgba(255, 255, 255, 0.2);
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.custom-checkbox.checked {
|
||||
background: linear-gradient(135deg, #ffb3b5, #ff5167);
|
||||
border-color: #ff5167;
|
||||
}
|
||||
.check-icon { width: 12px; height: 12px; color: #000; }
|
||||
```
|
||||
|
||||
#### radio → view + CSS 圆点
|
||||
|
||||
```vue
|
||||
<!-- 修复前: -->
|
||||
<radio :checked="selected === 'A'" @tap="selected = 'A'" color="#ffb3b5" />
|
||||
|
||||
<!-- 修复后: -->
|
||||
<view class="custom-radio" :class="{ checked: selected === 'A' }" @tap="selected = 'A'">
|
||||
<view v-if="selected === 'A'" class="radio-dot"></view>
|
||||
</view>
|
||||
```
|
||||
|
||||
```css
|
||||
.custom-radio {
|
||||
width: 18px; height: 18px; min-width: 18px;
|
||||
border-radius: 50%;
|
||||
border: 1.5px solid rgba(255, 255, 255, 0.2);
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.custom-radio.checked { border-color: #ff5167; }
|
||||
.radio-dot {
|
||||
width: 10px; height: 10px; border-radius: 50%;
|
||||
background: linear-gradient(135deg, #ffb3b5, #ff5167);
|
||||
}
|
||||
```
|
||||
|
||||
#### switch → view + CSS 滑动
|
||||
|
||||
```vue
|
||||
<!-- 修复前: -->
|
||||
<switch :checked="enabled" @change="enabled = !enabled" color="#ffb3b5" />
|
||||
|
||||
<!-- 修复后: -->
|
||||
<view class="custom-switch" :class="{ on: enabled }" @tap="enabled = !enabled">
|
||||
<view class="switch-thumb"></view>
|
||||
</view>
|
||||
```
|
||||
|
||||
```css
|
||||
.custom-switch {
|
||||
width: 44px; height: 24px; border-radius: 12px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
position: relative; transition: background 0.2s;
|
||||
}
|
||||
.custom-switch.on { background: linear-gradient(135deg, #ffb3b5, #ff5167); }
|
||||
.switch-thumb {
|
||||
width: 20px; height: 20px; border-radius: 50%;
|
||||
background: #fff; position: absolute; top: 2px; left: 2px;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
.custom-switch.on .switch-thumb { transform: translateX(20px); }
|
||||
```
|
||||
|
||||
### 关联修复规则
|
||||
|
||||
- 触发 FAIL 分类: ../rules/auto-fix/classification.md #23
|
||||
- 修复模板: ../rules/auto-fix/workflows.md AUTO-FIX #23 章节
|
||||
- ⛔ 禁止标记为"环境限制"跳过
|
||||
|
||||
@@ -208,11 +208,11 @@ Read fully and follow: ./modes/journey/journey-index.md
|
||||
|
||||
## 质量关卡
|
||||
|
||||
> 参见 ./rules/iron-laws.md 了解五大铁律和验证检查清单。
|
||||
> 参见 ./iron-laws.md 了解五大铁律和验证检查清单。
|
||||
|
||||
## E2E 测试
|
||||
|
||||
> 参见 ./rules/e2e-testing.md 了解 Playwright MCP 测试序列和视口规则。
|
||||
> 参见 ./e2e-testing.md 了解 Playwright MCP 测试序列和视口规则。
|
||||
|
||||
## 实战经验
|
||||
|
||||
|
||||
@@ -114,10 +114,9 @@
|
||||
|
||||
```html
|
||||
<style>
|
||||
/* phone-frame: iPhone 12+ 逻辑分辨率 390×844,border-box 下 414×868 = 390×844 内容区 + 12px×2 边框 */
|
||||
.phone-frame {
|
||||
width: 414px;
|
||||
height: 868px;
|
||||
width: 375px;
|
||||
height: 812px;
|
||||
border: 12px solid #1a1a1a;
|
||||
border-radius: 40px;
|
||||
overflow: hidden;
|
||||
@@ -128,10 +127,9 @@
|
||||
height: 100%;
|
||||
border: none;
|
||||
}
|
||||
/* grid 列宽 minmax(440px) 容纳 414px phone-frame + 容器内边距 */
|
||||
.prototype-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(440px, 1fr));
|
||||
grid-template-columns: repeat(auto-fill, 375px);
|
||||
gap: 24px;
|
||||
padding: 24px;
|
||||
justify-content: center;
|
||||
|
||||
Reference in New Issue
Block a user