视图引擎
尚未发布
@ahoo-wang/wow-view-engine 还没有发布到 npm。它仍在积极开发中,不承诺兼容:任何导出都可能改变形态,改动也不附带兼容层。本页描述目标用法,供你评估;暂时不要在生产环境依赖它。
视图引擎是面向 Wow 业务应用的数据视图引擎。应用在代码中声明“这份数据能怎样观察”:字段、类型、操作符、可用的分组与指标。用户在界面上决定“这次怎样观察”:筛选、列、排序、分组、图表和面板组合。引擎把这次选择编译成 Wow 查询,通过 @ahoo-wang/wow-client 执行,渲染结果,并把值得保留的观察方式保存下来,一键重新打开。
它是 @ahoo-wang/fetcher-viewer 的后继者;fetcher-viewer 留在 Fetcher 5.x,本站不再介绍。
要解决的问题
业务系统里的大多数页面其实是同一种页面:一个带筛选、排序和分页的列表,有时再加一张图。每个业务对象都复制一份;“再加一个筛选条件”“按仓库分组看看”这样的需求,每次都要改代码、排期、发版。数据没有变,变的只是观察方式。
| 面向 | 得到什么 |
|---|---|
| 业务用户 | 在声明的能力范围内调整范围、组织与呈现方式,保存常用视图并一键重新打开 |
| 研发 | 每个业务对象只写一个定义和一个查询客户端,不再为列表、分析、概览各写一套页面;筛选、分页、保存与冲突处理只实现一次 |
| 产品 | 支持范围内的呈现调整变成配置;新增业务对象只新增定义,引擎里不出现业务分支 |
它不是数据库,不是权限系统,不是通用的低代码页面搭建工具,也不是 BI 建模工具。数据、聚合能力和授权都来自 Wow 服务。
三条事实
设计先固定三条事实,其余都由它们推出:
| 事实 | 推论 |
|---|---|
| 定义是代码 | 没有定义服务,也没有定义版本。改定义就是一次部署;已保存的视图在打开时校验 |
| 配置是数据 | 只持久化 ViewInstance 和个人偏好。一致性靠乐观 revision 加幂等 requestId |
| 运行时状态是临时的 | 草稿、结果、分页和选择都只存在于一个打开的 ViewRuntime 中,从不持久化 |
视图
| 视图 | 用户做什么 |
|---|---|
| 明细 | 筛选状态为待处理,按创建时间排序,只保留需要的列,保存为“今日待处理” |
| 分析 | 按仓库分组,统计订单数并对金额求和,切换成柱状图 |
| 仪表盘 | 把几个视图放在同一页,用全局时间范围统一约束 |
| 嵌入视图或仪表盘 | 在业务页面里展示一个已保存的视图,例如某个客户的订单,不需要工作台 |
| 系统视图 | 在定义里声明“全部”“待处理”“本周新增”,用户一打开就有可用的视图 |
目标用法
这个包目前还不能安装。发布之后的安装方式是:
pnpm add @ahoo-wang/wow-view-engine @ahoo-wang/wow-client只有 /react 和 /ui 入口需要 react 与 react-dom;根入口可以在 Node 中运行。
1. 声明定义
import type { ViewDefinition } from '@ahoo-wang/wow-view-engine';
export const orders: ViewDefinition = {
id: 'orders',
title: 'Orders',
kind: 'data',
source: 'orders',
fields: [
{ name: 'id', label: 'Order', kind: 'string', sortable: true },
{
name: 'status',
label: 'Status',
kind: 'enum',
options: [
{ value: 'PENDING', label: 'Pending' },
{ value: 'SHIPPED', label: 'Shipped' },
],
},
{ name: 'warehouse', label: 'Warehouse', kind: 'string' },
{ name: 'amount', label: 'Amount', kind: 'number', summary: ['SUM', 'AVG'] },
{ name: 'createdAt', label: 'Created', kind: 'datetime', sortable: true },
],
// 行键必须可排序:每个明细查询的排序最后都以它收尾。
record: { rowKey: 'id', paging: 'paged', layouts: ['table', 'card'] },
};2. 创建引擎
import { MemoryViewStore, ViewEngine } from '@ahoo-wang/wow-view-engine';
const engine = new ViewEngine({
definitions: [orders],
store: new MemoryViewStore(),
// 来自 @ahoo-wang/wow-client 的 Pick<QueryApi, 'paged' | 'cursor' | 'aggregate'>
resolveSource: key => queryClients[key],
});MemoryViewStore 适合测试和示例。业务应用要针对自己的后端实现 ViewStore 端口,见参考。
3. 渲染工作台,或组合自己的界面
import '@ahoo-wang/wow-view-engine/styles.css';
import { DataWorkbench } from '@ahoo-wang/wow-view-engine/ui';
export function OrdersPage() {
return <DataWorkbench engine={engine} definitionId="orders" />;
}视图跟随页面的明暗,颜色取自 CSS 变量;预设、theme="system"、钉住与 shadcn 桥接见视图引擎的主题。
自定义布局使用 /react 入口的无头 Hook,例如 useOpenView、useViewRuntime、useFilterEditor 和 useRecordTable,用它们渲染任意标记,不需要接触引擎内部。
第一个完整示例围绕明细工作台展开:筛选待处理订单,调整列和排序,保存个人视图,再重新打开。它会随包一起发布。
在 Storybook 中试用
每种视图都在 Storybook 里用内存夹具运行,放在一个宿主应用外壳中。保存、改名和删除都写入每次打开时新建的内存存储。
| 视图 | Storybook |
|---|---|
| 明细 | 明细工作台及其筛选编辑器 |
| 分析 | 分析工作台 |
| 仪表盘 | 仪表盘 |
| 嵌入视图或仪表盘 | EmbeddedView 和 EmbeddedDashboard |
| 主题 | 主题一览与对比度矩阵 |
延伸阅读
- wow-view-engine 参考:入口、概念、持久化端口与扩展点。
- 视图引擎的主题:预设、宿主变量、亮暗与跟随系统、shadcn 桥接,以及覆盖变量要守的对比度。
- 设计文档:包发布之前以它为准。
- 包 README:API 的当前状态。