752 lines
17 KiB
Markdown
752 lines
17 KiB
Markdown
# 按钮扩展组件设计文档
|
||
|
||
> **版本:** v1.2.0
|
||
> **更新时间:** 2025-11-17
|
||
> **作者:** Nex Design Team
|
||
> **状态:** ✅ 已完成
|
||
|
||
---
|
||
|
||
## 📖 目录
|
||
|
||
1. [概述](#概述)
|
||
2. [设计方案](#设计方案)
|
||
3. [组件API](#组件api)
|
||
4. [使用指南](#使用指南)
|
||
5. [最佳实践](#最佳实践)
|
||
6. [更新日志](#更新日志)
|
||
|
||
---
|
||
|
||
## 概述
|
||
|
||
### 设计目标
|
||
|
||
为终端列表页面的按钮提供清晰的操作介绍和帮助信息,解决以下问题:
|
||
- 用户不了解按钮功能
|
||
- 复杂操作缺少引导
|
||
- 需要快速的上下文帮助
|
||
|
||
### 设计原则
|
||
|
||
1. **简洁至上** - 去除不必要的动画,使用扁平化设计
|
||
2. **功能独立** - 帮助功能不影响主操作流程
|
||
3. **易于理解** - 直观的图标和交互模式
|
||
4. **现代美学** - 符合Material Design和Fluent Design趋势
|
||
|
||
---
|
||
|
||
## 设计方案
|
||
|
||
我们提供了5种不同的设计方案,可根据实际场景选择使用:
|
||
|
||
### 方案1:增强型工具提示 (Enhanced Tooltip)
|
||
|
||
**特点:**
|
||
- 渐变色彩背景,视觉效果出众
|
||
- 支持标题、描述、快捷键、注意事项
|
||
- 带有脉冲动画的提示图标
|
||
- 响应式设计,移动端友好
|
||
|
||
**适用场景:**
|
||
- ✅ 简单操作,需要快速了解功能
|
||
- ✅ 不希望占用额外页面空间
|
||
- ✅ 信息量较少的提示
|
||
|
||
**效果预览:**
|
||
```
|
||
[按钮] (i) ← 脉冲动画图标
|
||
↓ 悬停
|
||
┌────────────────────────┐
|
||
│ 新增主机 │
|
||
│ 向系统中添加新的主机... │
|
||
│ 快捷键: Ctrl+N │
|
||
│ 注意: 请确保IP不冲突 │
|
||
└────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
### 方案2:智能帮助面板 (Smart Help Panel) ⭐ 推荐
|
||
|
||
**特点:**
|
||
- 侧边抽屉式设计,信息完整
|
||
- 实时显示当前悬停按钮的详细信息
|
||
- 包含使用场景、操作步骤、注意事项等
|
||
- 支持查看所有可用操作的快速索引
|
||
- 点击"?"图标直接打开帮助面板
|
||
|
||
**适用场景:**
|
||
- ✅ 复杂业务操作,需要详细说明
|
||
- ✅ 新用户培训和引导
|
||
- ✅ 功能较多,需要分步骤引导
|
||
|
||
**交互流程:**
|
||
```
|
||
1. 悬停按钮 → 出现"?"图标
|
||
2. 点击"?" → 打开右侧帮助面板
|
||
3. 显示详细内容:
|
||
- 功能说明
|
||
- 使用场景
|
||
- 操作步骤
|
||
- 注意事项
|
||
- 快捷键
|
||
- 权限要求
|
||
```
|
||
|
||
**特殊优化:**
|
||
- 面板打开时,鼠标离开按钮不会清空内容
|
||
- 点击"所有可用操作"卡片可切换内容
|
||
- 自动展开"当前操作"区域
|
||
|
||
---
|
||
|
||
### 方案3:悬浮展开卡片 (Hover Expand Card)
|
||
|
||
**特点:**
|
||
- 精美的悬浮卡片设计
|
||
- 滑入动画,视觉流畅
|
||
- 分层信息展示
|
||
- 使用React Portal渲染,永不被遮挡
|
||
|
||
**适用场景:**
|
||
- ✅ 需要展示较多信息
|
||
- ✅ 不想打断操作流程
|
||
- ✅ 希望信息就近显示
|
||
|
||
**技术实现:**
|
||
```jsx
|
||
// 使用Portal避免z-index遮挡问题
|
||
import { createPortal } from 'react-dom'
|
||
|
||
{createPortal(renderCard(), document.body)}
|
||
```
|
||
|
||
---
|
||
|
||
### 方案4:智能引导 (Smart Guide)
|
||
|
||
**特点:**
|
||
- 简洁扁平设计,独立帮助图标
|
||
- 点击查看弹窗式详细引导
|
||
- 包含步骤式操作说明
|
||
|
||
**适用场景:**
|
||
- ✅ 需要详细引导,但不希望干扰主流程
|
||
- ✅ 功能上线初期的用户引导
|
||
- ✅ 复杂操作的分步说明
|
||
|
||
**设计对比:**
|
||
```
|
||
旧版(已废弃):脉冲动画徽章,过于复杂
|
||
新版:简洁帮助图标,点击查看详情
|
||
|
||
┌────────────┐ ┌─┐
|
||
│ 新增主机 │ │?│ ← 简洁优雅
|
||
└────────────┘ └─┘
|
||
```
|
||
|
||
---
|
||
|
||
### 方案5:底部固定提示栏 (Bottom Hint Bar)
|
||
|
||
**特点:**
|
||
- 固定底部位置,不遮挡操作区域
|
||
- 实时更新,流畅切换
|
||
- 三种主题可选(渐变、浅色、深色)
|
||
|
||
**适用场景:**
|
||
- ✅ 需要始终可见的提示信息
|
||
- ✅ 不希望被tooltip遮挡操作区域
|
||
- ✅ 简单的实时信息展示
|
||
|
||
---
|
||
|
||
## 组件API
|
||
|
||
### ButtonWithTip
|
||
|
||
增强型工具提示按钮组件。
|
||
|
||
**Props:**
|
||
|
||
```typescript
|
||
interface ButtonWithTipProps {
|
||
label: string // 按钮文本
|
||
icon?: ReactNode // 按钮图标
|
||
type?: 'primary' | 'default' // 按钮类型
|
||
danger?: boolean // 是否为危险按钮
|
||
disabled?: boolean // 是否禁用
|
||
onClick?: () => void // 点击回调
|
||
size?: 'small' | 'middle' | 'large'
|
||
showTipIcon?: boolean // 是否显示提示图标
|
||
tip?: {
|
||
title?: string // 提示标题
|
||
description?: string // 详细描述
|
||
shortcut?: string // 快捷键
|
||
notes?: string[] // 注意事项
|
||
placement?: 'top' | 'bottom' | 'left' | 'right'
|
||
}
|
||
}
|
||
```
|
||
|
||
**使用示例:**
|
||
|
||
```jsx
|
||
import ButtonWithTip from '@/components/ButtonWithTip/ButtonWithTip'
|
||
|
||
<ButtonWithTip
|
||
label="新增主机"
|
||
icon={<PlusOutlined />}
|
||
type="primary"
|
||
tip={{
|
||
title: '新增主机',
|
||
description: '向系统中添加新的主机终端设备',
|
||
shortcut: 'Ctrl+N',
|
||
notes: ['请确保IP地址不与现有主机冲突', 'MAC地址必须唯一']
|
||
}}
|
||
onClick={handleAdd}
|
||
/>
|
||
```
|
||
|
||
---
|
||
|
||
### ActionHelpPanel
|
||
|
||
智能帮助面板组件(方案2)。
|
||
|
||
**Props:**
|
||
|
||
```typescript
|
||
interface ActionHelpPanelProps {
|
||
visible: boolean // 是否显示面板
|
||
onClose: () => void // 关闭回调
|
||
currentAction?: { // 当前操作信息
|
||
title: string
|
||
icon: ReactNode
|
||
description: string
|
||
scenarios?: string[] // 使用场景
|
||
steps?: string[] // 操作步骤
|
||
warnings?: string[] // 注意事项
|
||
shortcut?: string // 快捷键
|
||
permission?: string // 权限要求
|
||
badge?: {
|
||
text: string
|
||
color: string
|
||
}
|
||
}
|
||
allActions?: Array<Action> // 所有可用操作
|
||
placement?: 'left' | 'right' // 面板位置
|
||
onActionSelect?: (action: Action) => void // 选择操作回调
|
||
}
|
||
```
|
||
|
||
**使用示例:**
|
||
|
||
```jsx
|
||
import ActionHelpPanel from '@/components/ActionHelpPanel/ActionHelpPanel'
|
||
|
||
const [showPanel, setShowPanel] = useState(false)
|
||
const [currentAction, setCurrentAction] = useState(null)
|
||
|
||
// 在按钮外层添加hover和点击事件
|
||
<div
|
||
onMouseEnter={() => setCurrentAction(actionsConfig.add)}
|
||
onMouseLeave={() => !showPanel && setCurrentAction(null)}
|
||
>
|
||
<Button>新增主机</Button>
|
||
<button onClick={() => setShowPanel(true)}>?</button>
|
||
</div>
|
||
|
||
<ActionHelpPanel
|
||
visible={showPanel}
|
||
onClose={() => setShowPanel(false)}
|
||
currentAction={currentAction}
|
||
allActions={Object.values(actionsConfig)}
|
||
onActionSelect={(action) => setCurrentAction(action)}
|
||
/>
|
||
```
|
||
|
||
---
|
||
|
||
### ButtonWithHoverCard
|
||
|
||
悬浮展开卡片按钮组件(方案3)。
|
||
|
||
**Props:**
|
||
|
||
```typescript
|
||
interface ButtonWithHoverCardProps {
|
||
label: string
|
||
icon?: ReactNode
|
||
type?: 'primary' | 'default'
|
||
danger?: boolean
|
||
disabled?: boolean
|
||
onClick?: () => void
|
||
size?: 'small' | 'middle' | 'large'
|
||
cardInfo?: {
|
||
title: string
|
||
icon: ReactNode
|
||
description: string
|
||
scenarios?: string[]
|
||
quickTips?: string[]
|
||
warnings?: string[]
|
||
shortcut?: string
|
||
badge?: { text: string; color: string }
|
||
}
|
||
}
|
||
```
|
||
|
||
**技术要点:**
|
||
- 使用 `createPortal` 渲染卡片到 `document.body`
|
||
- 使用 `useRef` 获取按钮位置
|
||
- 避免z-index遮挡问题
|
||
|
||
---
|
||
|
||
### ButtonWithGuide
|
||
|
||
智能引导按钮组件(方案4)。
|
||
|
||
**Props:**
|
||
|
||
```typescript
|
||
interface ButtonWithGuideProps {
|
||
label: string
|
||
icon?: ReactNode
|
||
type?: 'primary' | 'default'
|
||
danger?: boolean
|
||
disabled?: boolean
|
||
onClick?: () => void
|
||
size?: 'small' | 'middle' | 'large'
|
||
guide?: {
|
||
title: string
|
||
icon: ReactNode
|
||
description: string
|
||
steps?: string[]
|
||
scenarios?: string[]
|
||
warnings?: string[]
|
||
shortcut?: string
|
||
permission?: string
|
||
badge?: { text: string; color: string }
|
||
}
|
||
}
|
||
```
|
||
|
||
**特点:**
|
||
- 简洁的帮助图标(不影响按钮文字)
|
||
- 点击打开弹窗式详细引导
|
||
- 包含步骤式说明(使用Ant Design Steps组件)
|
||
|
||
---
|
||
|
||
### BottomHintBar
|
||
|
||
底部固定提示栏组件(方案5)。
|
||
|
||
**Props:**
|
||
|
||
```typescript
|
||
interface BottomHintBarProps {
|
||
visible: boolean
|
||
hintInfo?: {
|
||
title: string
|
||
icon: ReactNode
|
||
description: string
|
||
quickTip?: string
|
||
warning?: string
|
||
shortcut?: string
|
||
badge?: { text: string; color: string }
|
||
}
|
||
onClose?: () => void
|
||
theme?: 'light' | 'dark' | 'gradient'
|
||
}
|
||
```
|
||
|
||
**使用示例:**
|
||
|
||
```jsx
|
||
import BottomHintBar from '@/components/BottomHintBar/BottomHintBar'
|
||
|
||
const [showHint, setShowHint] = useState(false)
|
||
const [hintInfo, setHintInfo] = useState(null)
|
||
|
||
<div
|
||
onMouseEnter={() => {
|
||
setHintInfo(actionConfig)
|
||
setShowHint(true)
|
||
}}
|
||
onMouseLeave={() => setShowHint(false)}
|
||
>
|
||
<Button>操作按钮</Button>
|
||
</div>
|
||
|
||
<BottomHintBar
|
||
visible={showHint}
|
||
hintInfo={hintInfo}
|
||
theme="gradient"
|
||
/>
|
||
```
|
||
|
||
---
|
||
|
||
## 使用指南
|
||
|
||
### 快速开始
|
||
|
||
1. **选择合适的方案**
|
||
|
||
根据使用场景选择组件:
|
||
|
||
| 场景 | 推荐方案 |
|
||
|------|---------|
|
||
| 简单列表页面,快速提示 | 方案1 增强型工具提示 |
|
||
| 复杂后台系统,详细引导 | 方案2 智能帮助面板 ⭐ |
|
||
| 数据密集页面,信息丰富 | 方案3 悬浮展开卡片 |
|
||
| 新功能上线,用户引导 | 方案4 智能引导 |
|
||
| 操作频繁,始终可见 | 方案5 底部固定提示栏 |
|
||
|
||
2. **导入组件**
|
||
|
||
```jsx
|
||
// 方案1
|
||
import ButtonWithTip from '@/components/ButtonWithTip/ButtonWithTip'
|
||
|
||
// 方案2
|
||
import ActionHelpPanel from '@/components/ActionHelpPanel/ActionHelpPanel'
|
||
|
||
// 方案3
|
||
import ButtonWithHoverCard from '@/components/ButtonWithHoverCard/ButtonWithHoverCard'
|
||
|
||
// 方案4
|
||
import ButtonWithGuide from '@/components/ButtonWithGuide/ButtonWithGuide'
|
||
|
||
// 方案5
|
||
import BottomHintBar from '@/components/BottomHintBar/BottomHintBar'
|
||
```
|
||
|
||
3. **配置操作信息**
|
||
|
||
建议将操作配置统一管理:
|
||
|
||
```jsx
|
||
const actionsConfig = {
|
||
add: {
|
||
title: '新增主机',
|
||
icon: <PlusOutlined />,
|
||
description: '向系统中添加新的主机终端设备',
|
||
scenarios: [
|
||
'当有新设备需要接入系统管理时',
|
||
'需要扩展终端设备数量时'
|
||
],
|
||
steps: [
|
||
'点击"新增主机"按钮',
|
||
'填写主机基本信息',
|
||
'选择主机所属分组',
|
||
'保存并等待主机上线'
|
||
],
|
||
warnings: [
|
||
'请确保IP地址不与现有主机冲突',
|
||
'MAC地址必须唯一且格式正确'
|
||
],
|
||
shortcut: 'Ctrl+N',
|
||
permission: '管理员权限',
|
||
badge: { text: '常用', color: 'blue' }
|
||
},
|
||
// ... 其他操作
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 方案2完整实现示例
|
||
|
||
```jsx
|
||
import { useState } from 'react'
|
||
import { Button } from 'antd'
|
||
import { PlusOutlined } from '@ant-design/icons'
|
||
import ActionHelpPanel from '@/components/ActionHelpPanel/ActionHelpPanel'
|
||
|
||
function MyPage() {
|
||
const [showHelpPanel, setShowHelpPanel] = useState(false)
|
||
const [currentAction, setCurrentAction] = useState(null)
|
||
|
||
// 处理悬停
|
||
const handleHover = (actionKey) => {
|
||
if (!showHelpPanel) {
|
||
setCurrentAction(actionsConfig[actionKey])
|
||
}
|
||
}
|
||
|
||
// 处理离开
|
||
const handleLeave = () => {
|
||
if (!showHelpPanel) {
|
||
setCurrentAction(null)
|
||
}
|
||
}
|
||
|
||
// 处理点击
|
||
const handleHelpClick = (e, actionKey) => {
|
||
e.stopPropagation()
|
||
setCurrentAction(actionsConfig[actionKey])
|
||
setShowHelpPanel(true)
|
||
}
|
||
|
||
return (
|
||
<div>
|
||
{/* 按钮区域 */}
|
||
<div
|
||
className="button-wrapper"
|
||
onMouseEnter={() => handleHover('add')}
|
||
onMouseLeave={handleLeave}
|
||
>
|
||
<Button type="primary" icon={<PlusOutlined />}>
|
||
新增主机
|
||
</Button>
|
||
<button
|
||
className="help-icon"
|
||
onClick={(e) => handleHelpClick(e, 'add')}
|
||
>
|
||
?
|
||
</button>
|
||
</div>
|
||
|
||
{/* 帮助面板 */}
|
||
<ActionHelpPanel
|
||
visible={showHelpPanel}
|
||
onClose={() => setShowHelpPanel(false)}
|
||
currentAction={currentAction}
|
||
allActions={Object.values(actionsConfig)}
|
||
onActionSelect={(action) => setCurrentAction(action)}
|
||
/>
|
||
</div>
|
||
)
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 最佳实践
|
||
|
||
### 1. 内容编写规范
|
||
|
||
**功能描述:**
|
||
- 用简洁的语言描述功能(1-2句话)
|
||
- 突出重点和目的
|
||
- 避免技术术语
|
||
|
||
**使用场景:**
|
||
- 列举2-4个实际使用场景
|
||
- 使用"当...时"的句式
|
||
- 帮助用户理解何时使用
|
||
|
||
**操作步骤:**
|
||
- 按实际操作顺序编写
|
||
- 每步一句话,清晰明确
|
||
- 使用动词开头
|
||
|
||
**注意事项:**
|
||
- 危险操作必须有明确警告
|
||
- 使用醒目的颜色标记
|
||
- 提供实际的使用建议
|
||
|
||
### 2. 性能优化
|
||
|
||
```jsx
|
||
// ✅ 使用useMemo缓存配置
|
||
const actionsConfig = useMemo(() => ({
|
||
add: { ... },
|
||
delete: { ... }
|
||
}), [])
|
||
|
||
// ✅ 防止不必要的重渲染
|
||
const handleHover = useCallback((key) => {
|
||
if (!showPanel) {
|
||
setCurrentAction(actionsConfig[key])
|
||
}
|
||
}, [showPanel, actionsConfig])
|
||
|
||
// ✅ 面板打开时避免hover更新
|
||
if (!showPanel) {
|
||
setCurrentAction(null)
|
||
}
|
||
```
|
||
|
||
### 3. 可访问性
|
||
|
||
```jsx
|
||
// 添加title属性
|
||
<button className="help-icon" title="查看帮助">
|
||
?
|
||
</button>
|
||
|
||
// 添加aria标签
|
||
<Button aria-label="新增主机">
|
||
新增主机
|
||
</Button>
|
||
|
||
// 快捷键支持
|
||
useEffect(() => {
|
||
const handleKeyPress = (e) => {
|
||
if (e.ctrlKey && e.key === 'n') {
|
||
handleAdd()
|
||
}
|
||
}
|
||
window.addEventListener('keydown', handleKeyPress)
|
||
return () => window.removeEventListener('keydown', handleKeyPress)
|
||
}, [])
|
||
```
|
||
|
||
### 4. 响应式适配
|
||
|
||
```css
|
||
/* 移动端隐藏某些提示 */
|
||
@media (max-width: 768px) {
|
||
.help-icon {
|
||
display: none;
|
||
}
|
||
|
||
.hover-info-card {
|
||
width: 100%;
|
||
left: 0 !important;
|
||
transform: translateY(-50%);
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 更新日志
|
||
|
||
### v1.2.0 (2025-11-17)
|
||
|
||
**新增:**
|
||
- ✨ 新增 `ButtonWithGuide` 组件,替代复杂的徽章设计
|
||
- ✨ 方案2添加 `onActionSelect` 回调,支持点击卡片切换内容
|
||
|
||
**修复:**
|
||
- 🐛 修复方案2点击"?"后内容消失的问题
|
||
- 🐛 修复方案2"所有可用操作"卡片无法点击的问题
|
||
- 🐛 修复方案3悬浮卡片被Card遮挡(使用Portal)
|
||
- 🐛 修复菜单图标,从 `GlobalOutlined` 改为 `BlockOutlined`
|
||
|
||
**优化:**
|
||
- 💄 简化方案4设计,去掉复杂的脉冲动画
|
||
- 💄 方案2面板打开时不响应鼠标hover事件
|
||
- 💄 提升整体视觉一致性
|
||
|
||
### v1.1.0 (2025-11-17)
|
||
|
||
**新增:**
|
||
- ✨ 新增 `ActionHelpPanel` 智能帮助面板组件
|
||
- ✨ 新增 `BottomHintBar` 底部提示栏组件
|
||
- ✨ 方案2添加点击"?"图标直接打开面板功能
|
||
|
||
**修复:**
|
||
- 🐛 修复 `ButtonWithTip` 的 Tooltip overlayClassName 警告
|
||
- 🐛 修复 `AppSider` 的 findDOMNode 警告(使用 items 配置)
|
||
- 🐛 修复方案5底部提示栏鼠标移动时闪烁的问题
|
||
|
||
**优化:**
|
||
- 💄 为方案2按钮添加悬停时的"?"图标提示
|
||
- 💄 提升方案3悬浮卡片的 z-index 和阴影效果
|
||
|
||
### v1.0.0 (2025-11-17)
|
||
|
||
**初始版本:**
|
||
- 🎉 发布5种按钮扩展设计方案
|
||
- 📦 提供完整的组件API和使用文档
|
||
- 📝 提供详细的设计指南和最佳实践
|
||
|
||
---
|
||
|
||
## 技术架构
|
||
|
||
### 依赖项
|
||
|
||
```json
|
||
{
|
||
"react": "^18.2.0",
|
||
"react-dom": "^18.2.0",
|
||
"antd": "^5.x",
|
||
"@ant-design/icons": "^5.x"
|
||
}
|
||
```
|
||
|
||
### 目录结构
|
||
|
||
```
|
||
src/components/
|
||
├── ButtonWithTip/
|
||
│ ├── ButtonWithTip.jsx
|
||
│ └── ButtonWithTip.css
|
||
├── ActionHelpPanel/
|
||
│ ├── ActionHelpPanel.jsx
|
||
│ └── ActionHelpPanel.css
|
||
├── ButtonWithHoverCard/
|
||
│ ├── ButtonWithHoverCard.jsx
|
||
│ └── ButtonWithHoverCard.css
|
||
├── ButtonWithGuide/
|
||
│ ├── ButtonWithGuide.jsx
|
||
│ └── ButtonWithGuide.css
|
||
└── BottomHintBar/
|
||
├── BottomHintBar.jsx
|
||
└── BottomHintBar.css
|
||
|
||
src/pages/
|
||
└── AllButtonDesigns.jsx # 演示页面
|
||
|
||
docs/
|
||
└── components/
|
||
└── ButtonExtensions.md # 本文档
|
||
```
|
||
|
||
---
|
||
|
||
## 常见问题
|
||
|
||
### Q1: 如何选择合适的方案?
|
||
|
||
**A:** 根据以下因素选择:
|
||
- **信息量**:少 → 方案1,多 → 方案2/3
|
||
- **复杂度**:简单 → 方案1/5,复杂 → 方案2/4
|
||
- **使用频率**:频繁 → 方案5,偶尔 → 方案1/3
|
||
- **用户类型**:新手 → 方案2/4,熟练 → 方案1/5
|
||
|
||
### Q2: 可以混合使用多种方案吗?
|
||
|
||
**A:** 可以。建议:
|
||
- 同一页面使用统一的方案
|
||
- 不同页面可以使用不同方案
|
||
- 核心操作使用方案2,次要操作使用方案1
|
||
|
||
### Q3: 如何自定义样式?
|
||
|
||
**A:** 所有组件都支持自定义样式:
|
||
|
||
```jsx
|
||
// 通过className
|
||
<ButtonWithTip className="my-custom-button" />
|
||
|
||
// 通过style
|
||
<ButtonWithTip style={{ marginRight: 16 }} />
|
||
|
||
// 修改CSS变量
|
||
:root {
|
||
--tip-primary-gradient: linear-gradient(...);
|
||
}
|
||
```
|
||
|
||
### Q4: 移动端如何适配?
|
||
|
||
**A:** 所有组件都内置了响应式支持:
|
||
- 方案1:移动端隐藏提示图标
|
||
- 方案2:面板宽度自适应
|
||
- 方案3:卡片居中显示
|
||
- 方案5:提示栏自适应布局
|
||
|
||
---
|
||
|
||
**最后更新:** 2025-11-17
|
||
**文档版本:** v1.2.0
|