iter(g304): 配方补可排序检查单(句柄式拼装)

This commit is contained in:
HIsheR
2026-10-27 00:33:10 +08:00
parent b24da598d1
commit 0851de91a1
4 changed files with 58 additions and 0 deletions
+24
View File
@@ -407,6 +407,30 @@ const panel = h('div', { class: 'review' },
- `codeBlock` 的行号不参与复制,`copyButton` 直接读原文,所以「复制出来的代码」永远干净。
- 差异行多了给 `diffView` 外层限定高度(或放进抽屉),否则长差异会把审阅按钮挤出视口。
## 配方 19:可排序的检查单(拖拽 + 键盘搬位 + 顺序回写)
```ts
const steps = ['需求评审', '接口联调', '灰度发布', '线上回归'];
const order = signal(steps); // 顺序唯一真相:组件与下方摘要读同一个信号
const list = sortableList({
items: steps, // 文案即排序键,要求唯一
value: order,
onChange: (next) => toast.success(`已调整:${next[0]} 置顶`),
});
card({ title: '发布检查单(可拖动,Alt+↑↓ 键盘搬位)' },
list.el, // 返回的是句柄不是节点:忘了 append(el) 页面上一片空白
h('p', { class: 'desc' }, () => order().map((t, i) => `${i + 1}. ${t}`).join(' ')),
button({ label: '把「灰度发布」置顶', variant: 'ghost', onClick: () => list.move(2, 0) }),
);
```
要点:
- `sortableList` 返回 `{ el, move, order }` 句柄(与 `form` / `virtualList` 同类):节点在 `el` 上,业务侧要改顺序用 `move(from, to)`,读当前顺序用 `order()`。
- 顺序只存一份:`value` 信号同时喂组件与摘要 / 上报逻辑,否则会出现「界面拖了、提交的仍是老顺序」。
- `move()` 与拖拽走同一条提交路径(都会触发 `onChange`),所以「置顶 / 上移」按钮不必另写状态同步;越界下标静默忽略,不用自己判边界。
- 拖到边缘不会自动滚动:条目多到一屏放不下时改用筛选或上下移按钮,不要指望拖出视口;跨列表搬运用两个实例各持一个信号。
- 条目文案要唯一——重名会让「谁被搬走了」失去参照,需要重复内容时把序号拼进文案(`'确认条款 #1'`)。
## 通用约定
- 状态一律放信号(`signal` / `computed`),组件只读写信号,不持有业务数据副本。