8.8 KiB
8.8 KiB
合同起草页面 UI 修复
修复内容
1. 修复 json 弃用警告
问题:
"json"已弃用。ts(6385)
This utility is deprecated in favor of opting into Single Fetch via future.v3_singleFetch
and returning raw objects. This method will be removed in React Router v7.
解决方案:
使用 Response.json() 替代 Remix 的 json() 函数。
修改的代码:
// ❌ 旧代码(已弃用)
import { json, redirect } from '@remix-run/node';
export async function loader() {
return json({ data });
}
export async function action() {
return json({ success: true }, { status: 200 });
}
// ✅ 新代码(使用标准 Web API)
import { redirect } from '@remix-run/node';
export async function loader() {
return Response.json({ data });
}
export async function action() {
return Response.json({ success: true }, { status: 200 });
}
优势:
- 使用标准 Web API,兼容性更好
- 未来 React Router v7 不会移除
- 符合现代 Web 标准
2. 修复 FilePreview 高度问题
问题: FilePreview 组件没有占满父级容器的高度,导致页面布局不完整。
根本原因:
- 父容器没有高度限制
- FilePreview 根元素没有设置
h-full - 内容区域使用固定的
maxHeight: calc(100vh - 150px),不适用于嵌套布局
解决方案:
修改 1:父容器添加高度
app/routes/contract-draft.$draftId.tsx:
// ❌ 旧代码
<div className="w-[60%] border-r border-gray-200 bg-white">
<FilePreview ... />
</div>
<div className="w-[40%] bg-white">
<PlaceholderForm ... />
</div>
// ✅ 新代码
<div className="w-[60%] border-r border-gray-200 bg-white h-full overflow-hidden">
<FilePreview ... />
</div>
<div className="w-[40%] bg-white h-full overflow-hidden">
<PlaceholderForm ... />
</div>
变化:
- 添加
h-full- 高度占满父容器 - 添加
overflow-hidden- 防止内容溢出
修改 2:FilePreview 根元素使用 Flex 布局
app/components/reviews/FilePreview.tsx:
// ❌ 旧代码
return (
<div className="file-preview">
<div className="file-preview-header ...">...</div>
<div className="file-preview-content" style={{ maxHeight: 'calc(100vh - 150px)' }}>...</div>
</div>
);
// ✅ 新代码
return (
<div className="file-preview h-full flex flex-col">
<div className="file-preview-header ... flex-shrink-0">...</div>
<div className="file-preview-content flex-1 overflow-auto">...</div>
</div>
);
变化:
- 根元素:添加
h-full flex flex-col- 占满高度,使用垂直 Flex 布局 - Header:添加
flex-shrink-0- 固定高度,不压缩 - Content:使用
flex-1 overflow-auto替代固定maxHeight- 占据剩余空间,自动滚动
布局原理
Flex 布局结构
┌─────────────────────────────────────────┐
│ h-screen flex flex-col │ ← 全屏容器
├─────────────────────────────────────────┤
│ 顶部工具栏 (固定高度) │ ← flex-shrink-0
├─────────────────────────────────────────┤
│ flex-1 flex overflow-hidden │ ← 主内容区(占据剩余空间)
│ ┌─────────────┬─────────────────────┐ │
│ │ w-[60%] │ w-[40%] │ │
│ │ h-full │ h-full │ │
│ │ ┌─────────┐ │ ┌─────────────────┐ │ │
│ │ │FilePreview│ │PlaceholderForm │ │ │
│ │ │h-full │ │ │ │ │
│ │ │flex-col │ │ │ │ │
│ │ │┌────────┐│ │ │ │ │
│ │ ││Header ││ │ │ │ │
│ │ ││(固定) ││ │ │ │ │
│ │ │├────────┤│ │ │ │ │
│ │ ││Content ││ │ │ │ │
│ │ ││flex-1 ││ │ │ │ │
│ │ ││(自适应)││ │ │ │ │
│ │ │└────────┘│ │ │ │ │
│ │ └─────────┘ │ └─────────────────┘ │ │
│ └─────────────┴─────────────────────┘ │
└─────────────────────────────────────────┘
关键 CSS 类
| 类名 | 作用 | 使用位置 |
|---|---|---|
h-screen |
高度 100vh | 根容器 |
flex flex-col |
垂直 Flex 布局 | 根容器、FilePreview |
flex-1 |
占据剩余空间 | 主内容区、Content |
h-full |
高度 100% | 左右侧容器、FilePreview |
overflow-hidden |
隐藏溢出 | 左右侧容器 |
overflow-auto |
自动滚动 | Content 区域 |
flex-shrink-0 |
不压缩 | Header |
测试验证
1. 启动开发服务器
npm run dev
2. 访问草稿页面
http://localhost:5173/contract-draft/1
3. 验证布局
✅ 应该看到:
- 页面占满整个屏幕(无滚动条)
- 左侧文档预览占 60% 宽度,高度占满
- 右侧表单占 40% 宽度,高度占满
- FilePreview 内容区域可以独立滚动
- 表单区域可以独立滚动
✅ 不应该看到:
- FilePreview 底部有空白
- 页面外层有滚动条(应该在内容区域内滚动)
- 布局错乱或内容溢出
4. 响应式测试
- 调整浏览器窗口大小
- FilePreview 和 PlaceholderForm 应该始终占满高度
- 内容区域应该自动调整滚动
修改的文件
1. app/routes/contract-draft.$draftId.tsx
变化:
- ✅ 移除
json导入 - ✅ 所有
json()替换为Response.json() - ✅ 左右侧容器添加
h-full overflow-hidden
位置:
- Line 7: 移除
json导入 - Line 104:
Response.json({ draft, template }) - Line 117, 123, 138, 141, 144:
Response.json() - Line 353, 374: 添加
h-full overflow-hidden
2. app/components/reviews/FilePreview.tsx
变化:
- ✅ 根元素添加
h-full flex flex-col - ✅ Header 添加
flex-shrink-0 - ✅ Content 改用
flex-1 overflow-auto,移除固定maxHeight
位置:
- Line 429:
<div className="file-preview h-full flex flex-col"> - Line 430: Header 添加
flex-shrink-0 - Line 525:
<div className="file-preview-content flex-1 overflow-auto">
常见问题
Q1: FilePreview 仍然没有占满高度
原因:浏览器缓存了旧的样式
解决:
- 硬刷新页面(Ctrl+Shift+R 或 Cmd+Shift+R)
- 清除浏览器缓存
- 重启开发服务器
Q2: 内容区域滚动不流畅
原因:可能是 overflow-hidden 和 overflow-auto 冲突
解决:
确保父容器使用 overflow-hidden,子容器(内容区域)使用 overflow-auto
Q3: 在其他页面 FilePreview 布局变了
影响范围:此修改影响所有使用 FilePreview 的页面
如果出现问题:
- 检查该页面的父容器是否有足够的高度
- 可能需要给父容器添加
h-full或明确的高度值 - 或者给 FilePreview 添加一个 prop 来控制是否使用 flex 布局
Q4: 响应式布局问题
现象:小屏幕下布局错乱
解决: 可以添加响应式类,例���:
<div className="w-full md:w-[60%] h-full overflow-hidden">
后续优化
1. 添加 prop 控制布局模式(可选)
interface FilePreviewProps {
// ... existing props
layoutMode?: 'flex' | 'fixed'; // 新增:控制布局模式
}
// 在组件中使用
<div className={`file-preview ${layoutMode === 'flex' ? 'h-full flex flex-col' : ''}`}>
2. 优化滚动性能
<div
className="file-preview-content flex-1 overflow-auto"
style={{ scrollBehavior: 'smooth' }} // 平滑滚动
>
3. 添加加载状态
在文档加载时显示骨架屏或加载动画,占满高度,避免布局跳动。
总结
✅ 已修复:
json弃用警告 - 使用Response.json()- FilePreview 高度问题 - 使用 Flex 布局占满父容器
✅ 布局改进:
- 使用现代 Flex 布局替代固定高度
- 更好的响应式支持
- 内容区域独立滚动
✅ 代码质量:
- 符合 Web 标准
- 更易维护
- 类型检查通过
🎯 可以开始测试了!页面布局应该正常了。