154 lines
7.9 KiB
Markdown
154 lines
7.9 KiB
Markdown
---
|
||
name: grid-component
|
||
overview: 在 fms-vue 的 src/components/ui/grid 下新建 Grid 组件(Row + Col),参考 antdv-next 的 24 栅格设计与本项目开发规范,使用纯 CSS + scoped SCSS 实现,不引入新依赖、不破坏现有 token。
|
||
todos:
|
||
- id: grid-tokens
|
||
content: tokens.css 新增 --fms-grid-gutter 默认值(用 [skill:antdv-next] 确认断点)
|
||
status: pending
|
||
- id: grid-style
|
||
content: 创建 grid/index.scss:24 栅格类、offset/order/push/pull/flex、xs~xxxl 媒体查询与 gutter 变量
|
||
status: pending
|
||
dependencies:
|
||
- grid-tokens
|
||
- id: grid-row
|
||
content: 创建 row.vue:flex 容器、gutter 负 margin/row-gap、align/justify/wrap 与 CSS 变量下传
|
||
status: pending
|
||
dependencies:
|
||
- grid-style
|
||
- id: grid-col
|
||
content: 创建 col.vue:span/offset/order/push/pull/flex 及响应式 xs~xxxl(数字 class + 对象 computed style)
|
||
status: pending
|
||
dependencies:
|
||
- grid-style
|
||
- id: grid-demo
|
||
content: 创建 demo/grid.vue 并注册到 App.vue「布局」分类与 demoMap
|
||
status: pending
|
||
dependencies:
|
||
- grid-row
|
||
- grid-col
|
||
- id: grid-verify
|
||
content: oxlint 静态检查 grid 相关文件并汇报(不主动构建)
|
||
status: pending
|
||
dependencies:
|
||
- grid-demo
|
||
---
|
||
|
||
## 用户需求
|
||
|
||
参考 `fms-vue/开发规范.md` 与 `fms/参考组件库/antdv-next` 的 Grid 组件,在 `fms-vue` 组件库中新增 Grid 栅格组件。
|
||
|
||
## 产品概述
|
||
|
||
基于 24 栅格系统的布局组件,包含 `Row` 容器与 `Col` 列两个组件,用于快速搭建响应式页面布局。参考 antdv-next 的 API 设计与交互语义,遵循本项目 Vue 3 + scoped SCSS + `--fms-*` token 的约定。
|
||
|
||
## 核心特性
|
||
|
||
- Row:flex 行容器,支持 `gutter`(水平/垂直间距)、`align`(top/middle/bottom/stretch)、`justify`(start/end/center/space-around/space-between/space-evenly)、`wrap` 控制换行。
|
||
- Col:列单元,支持 `span`(0-24)、`offset`、`order`、`push`、`pull`、`flex`;并支持响应式 `xs/sm/md/lg/xl/xxl/xxxl`(数字或 `{span,offset,order,push,pull,flex}` 对象),按断点自动切换布局。
|
||
- 响应式断点对齐 antdv-next 默认:576 / 768 / 992 / 1200 / 1600 / 1920,采用纯 CSS media query 实现,无 JS 监听开销。
|
||
- gutter 水平间距由 Row 负 margin 抵消、Col 对称 padding 实现;垂直间距由 Row `row-gap` 实现。
|
||
- 间距默认值通过 `tokens.css` 新增 `--fms-grid-gutter`(默认 0),演示中传入具体值。
|
||
- 提供演示页面,展示基础栅格、gutter、对齐、偏移、响应式等典型用法。
|
||
|
||
## 技术栈
|
||
|
||
- Vue 3 `<script setup>` + TypeScript(props 类型),scoped SCSS(`@use './index.scss'`)
|
||
- 纯 CSS 栅格(24 栅格百分比宽度 + flex 布局),不引入新依赖、不依赖 JS 断点监听
|
||
- 复用 `src/theme/tokens.css` 的 `--fms-*` token;新增 `--fms-grid-gutter`
|
||
|
||
## 实现方案
|
||
|
||
### 策略
|
||
|
||
参照 antdv-next `grid/` 的 API(row.tsx、col.tsx、index.tsx)做 Vue 化移植:Row 负责 flex 容器与 gutter 负边距/row-gap,Col 负责 span/offset/order/push/pull/flex 及响应式对象。与 antdv-next 用 `useBreakpoint` JS 监听的差异点:**本项目用纯 CSS `@media` 实现响应式**,更轻量、零运行时开销,符合开发规范"性能优先"底线。
|
||
|
||
### 关键技术决策
|
||
|
||
1. **响应式纯 CSS 化**:24 栅格类(`.fms-col-{n}` 等 `n∈0..24`)与 `xs~xxxl` 媒体查询全部由 SCSS 静态生成,避免 JS `resize` 监听与重渲染。断点值硬编码在 `grid/index.scss` 的 `@media` 中(Grid 本职,不污染全局断点 token)。
|
||
2. **gutter 实现**:Row 水平 gutter 用负左右 margin(`-gutter/2`),Col 用对称左右 padding(`gutter/2`);垂直 gutter 用 Row `row-gap`。gutter 支持数字或 `[h, v]` 数组,由 Row 以 CSS 变量 `--fms-grid-gutter-h/-v` 下传,Col 读取使用,避免每行重复计算。
|
||
3. **响应式对象注入**:Col 的 `xs~xxxl` 接受数字或对象;数字映射到预设 class,对象(含 span/offset/order/push/pull/flex)通过 `computed` 生成 inline `style` 对象注入,仅在断点 media query 激活时生效(用 SCSS 生成对应断点下的 class 或行内 style 结合媒体查询)。
|
||
4. **API 收敛**:仅实现需求明确的 props;枚举(`align`/`justify`)提供 `validator`;不提供 `size` 枚举(符合规范 7.1)。
|
||
5. **组件命名**:`defineOptions({ name: 'FmsRow' })` / `'FmsCol'`,与现有 `FmsSpin` 模式一致。
|
||
|
||
### 性能与可靠性
|
||
|
||
- 静态 class + CSS 变量,无高频事件、无布局读取、无定时器,卸载无残留监听。
|
||
- gutter 变量由 Row 计算一次(computed),Col 通过 CSS 变量继承,避免每列重复计算。
|
||
- `prefers-reduced-motion` 无需处理(Grid 无动画)。
|
||
|
||
## 实现备注
|
||
|
||
- 复用现有 `.fms-<name>` 命名与 `index.scss` 引入方式(参考 splitter/index.scss)。
|
||
- 不创建 barrel index(规范 3)。
|
||
- 演示注册到 `App.vue`「布局」分类与 demoMap,与 Spin 注册方式一致。
|
||
- 不主动执行 `pnpm build`,仅做 oxlint 静态检查(规范 2)。
|
||
|
||
## 架构设计
|
||
|
||
```mermaid
|
||
graph TD
|
||
A[页面/示例] --> B[Row 容器]
|
||
B --> C[Col 列]
|
||
B -->|提供 gutter CSS 变量| C
|
||
C -->|span/offset/order/push/pull/flex + 响应式| D[SCSS 栅格类与 media query]
|
||
B -->|align/justify/wrap| D
|
||
```
|
||
|
||
Row 与 Col 通过 CSS 变量(`--fms-grid-gutter-h/-v`)传递间距,栅格类与响应式断点全部由 `index.scss` 静态生成。
|
||
|
||
## 目录结构
|
||
|
||
```
|
||
fms-vue/src/components/ui/grid/
|
||
row.vue # [NEW] Row 容器组件。实现 flex 布局、gutter 负 margin/row-gap、align/justify/wrap;将 gutter 拆为 --fms-grid-gutter-h/-v CSS 变量下传。
|
||
col.vue # [NEW] Col 列组件。实现 span/offset/order/push/pull/flex 与响应式 xs~xxxl(数字→class,对象→computed style);读取 Row 下传的 gutter 变量。
|
||
index.scss # [NEW] 栅格样式。24 栅格类、flex/order/offset/push/pull 类、xs~xxxl 媒体查询(断点 576/768/992/1200/1600/1920)、gutter 变量使用。
|
||
fms-vue/src/theme/tokens.css # [MODIFY] :root 新增 --fms-grid-gutter(默认 0),不随主题变化。
|
||
fms-vue/src/components/ui/demo/grid.vue # [NEW] 演示:基础栅格、gutter、对齐、偏移、响应式。
|
||
fms-vue/src/App.vue # [MODIFY] 引入 grid demo,注册到「布局」分类,加入 demoMap。
|
||
```
|
||
|
||
## 关键代码结构
|
||
|
||
```ts
|
||
// col.vue props(节选)
|
||
const props = defineProps({
|
||
span: { type: [Number, String], default: undefined },
|
||
offset: { type: [Number, String], default: undefined },
|
||
order: { type: [Number, String], default: undefined },
|
||
push: { type: [Number, String], default: undefined },
|
||
pull: { type: [Number, String], default: undefined },
|
||
flex: { type: [Number, String], default: undefined },
|
||
xs: { type: [Number, Object], default: undefined },
|
||
sm: { type: [Number, Object], default: undefined },
|
||
md: { type: [Number, Object], default: undefined },
|
||
lg: { type: [Number, Object], default: undefined },
|
||
xl: { type: [Number, Object], default: undefined },
|
||
xxl: { type: [Number, Object], default: undefined },
|
||
xxxl: { type: [Number, Object], default: undefined },
|
||
})
|
||
|
||
// row.vue props(节选)
|
||
const props = defineProps({
|
||
gutter: { type: [Number, Array], default: 0 },
|
||
align: {
|
||
type: String,
|
||
default: undefined,
|
||
validator: (v) => ['top', 'middle', 'bottom', 'stretch'].includes(v),
|
||
},
|
||
justify: {
|
||
type: String,
|
||
default: undefined,
|
||
validator: (v) => ['start', 'end', 'center', 'space-around', 'space-between', 'space-evenly'].includes(v),
|
||
},
|
||
wrap: { type: Boolean, default: true },
|
||
})
|
||
```
|
||
|
||
## Agent Extensions
|
||
|
||
### Skill
|
||
|
||
- **antdv-next**
|
||
- Purpose: 获取 Grid 组件的 API、props/events/slots 定义与语义设计参考,确保移植忠于原库交互。
|
||
- Expected outcome: 确认 Row/Col 的 props 集合、断点值与 gutter 实现细节,指导 Vue 化实现。 |