---
description: "列表页的记忆件：把当前的 { search, filters, sort } 拍成快照、起名存住，下次一键套用，不必每天手调同一组条件。「低库存」「本周待审」这类高频组合，就该各是一个视图"
---

# 保存视图（命名筛选预设）

列表页的记忆件：把当前的 `{ search, filters, sort }` 拍成快照、起名存住，下次一键套用，不必每天手调同一组条件。「低库存」「本周待审」这类高频组合，就该各是一个视图。

<iframe src="/skills/dashboard/assets/demo-saved-views.html"
        style="width:100%;height:620px;border:1px solid #8884;border-radius:10px"
        loading="lazy" title="形状 demo：保存视图"></iframe>

试这几下：

- 点**低库存** —— 筛选、排序一次到位，活跃视图 chip 高亮
- 在活跃视图下改任意条件 —— chip 标**已修改**，可「更新」回写原视图，或「另存为」新视图
- 自己调一组条件 → **＋ 保存当前视图** → 输入名字，新 chip 出现并立即变为活跃
- 点 chip 上的 × 删除（先确认，后 toast）；重新加载页面，视图仍在

## 规矩

- **视图是快照**：保存、更新、套用都对 `{ search, filters, sort }` 深拷贝（`structuredClone`），之后再改页面条件，动不到已存的视图
- **`storageKey` 按资源命名空间**（如 `saved-views:products`），持久化写回读取用的同一个 key，各页视图互不串
- **存储访问带守卫**：`typeof window` + try/catch，视图在挂载后的 `useEffect` 里水合，服务端与首帧客户端渲染一致。demo（与蓝本模板）持久化在 localStorage，真实版把同一对读写函数换到用户偏好即可
- 真实资源上列表状态在 URL 里（`useTableSearch`），`onApply` 应导航到保存的 `ViewState` 而不是 `setState`，`current` 也从 URL 派生

> 蓝本：`add-saved-views.md`[^add-saved-views]（open-dashboard @ `aa9815f`，MIT，Invariants 已消化进上面「规矩」）

??? abstract "demo 源码：`assets/demo-saved-views.html`（自包含、未压缩）"

    ```html
    --8<-- "skills/dashboard/assets/demo-saved-views.html"
    ```

[^add-saved-views]: [`add-saved-views.md`](https://github.com/ahpxex/open-dashboard/blob/aa9815f426e9520841c4aa15a341bfd9f866091f/.claude/skills/add-component/references/add-saved-views.md)，2026-07-28 读。
