7.1 KiB
7.1 KiB
页面结构文件扩展名更新说明
📝 更新内容
根据开发安全性的要求,已将所有模块页面结构示例中的 JavaScript 文件(.js)改为 TypeScript 文件(.tsx),以提供更好的类型安全性。
🔄 修改的文件类型
1. Hooks 文件
usePageData.js→usePageData.tsxusePageActions.js→usePageActions.tsxuseClassification.js→useClassification.tsxuseQRCode.js→useQRCode.tsxuseDriverForm.js→useDriverForm.tsxuseTaskManagement.js→useTaskManagement.tsxuseLoadDevice.js→useLoadDevice.tsxuseRealtimeLocation.js→useRealtimeLocation.tsxuseWebSocket.js→useWebSocket.tsx- 等等...
2. Utils 文件
pageHelpers.js→pageHelpers.tsxformatters.js→formatters.tsxvalidators.js→validators.tsxcoordinateUtils.js→coordinateUtils.tsxareaCalculators.js→areaCalculators.tsxcategoryHelpers.js→categoryHelpers.tsxqrGenerators.js→qrGenerators.tsxtaskHelpers.js→taskHelpers.tsxloadCalculators.js→loadCalculators.tsxmapHelpers.js→mapHelpers.tsx- 等等...
3. Constants 文件
constants.js→constants.tsx
4. Common 组件文件
LoadingSpinner.jsx→LoadingSpinner.tsxErrorBoundary.jsx→ErrorBoundary.tsxEmptyState.jsx→EmptyState.tsxConfirmDialog.jsx→ConfirmDialog.tsx
📂 标准页面结构(已更新)
PageName/
├── 📄 index.jsx # 主组件
├── 📄 index.css # 样式文件
├── 📄 index.types.ts # 类型定义
├── 📂 hooks/ # 页面专用Hooks
│ ├── 📄 usePageData.tsx # 数据管理Hook
│ ├── 📄 usePageActions.tsx # 操作Hook
│ └── 📄 use[Feature].tsx # 特定功能Hook
├── 📂 utils/ # 工具函数
│ ├── 📄 pageHelpers.tsx # 页面辅助函数
│ ├── 📄 validators.tsx # 表单验证
│ └── 📄 formatters.tsx # 数据格式化
├── 📄 constants.tsx # 页面常量
└── 📂 components/ # 子组件目录
└── 📂 [ComponentName]/ # 子组件
├── 📄 index.jsx
├── 📄 index.css
└── 📄 types.ts
✅ 已更新的文档
- ✅ AgriculturalMachinery模块页面结构示例.md - 已完成
- ✅ LandInformation模块页面结构示例.md - 已完成
- 🔄 FarmingOperation模块页面结构示例.md - 需要继续更新
- 🔄 其他业务模块页面结构示例.md - 需要继续更新
- ✅ Pages目录结构与开发规范.md - 已完成
- ✅ 开发者参考指南.md - 已完成
- ✅ Pages目录结构设计总结.md - 已完成
💡 开发建议
1. TypeScript 类型安全
使用 .tsx 文件可以享受以下好处:
- 完整的类型检查
- 更好的 IDE 支持
- 减少运行时错误
- 更容易的重构
- 更好的代码提示
2. Hook 开发示例
// hooks/usePageData.tsx
import { useState, useEffect, useCallback } from 'react';
import { getApiData } from '@/apis/module';
import { showMessage } from '@/utils/message';
import { DataRecord, Filters, PaginationState } from './index.types';
export function usePageData() {
const [data, setData] = useState<DataRecord[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [filters, setFilters] = useState<Filters>({});
const [pagination, setPagination] = useState<PaginationState>({
current: 1,
pageSize: 10,
total: 0
});
// 获取数据
const fetchData = useCallback(async () => {
setLoading(true);
setError(null);
try {
const params = {
...filters,
page: pagination.current,
pageSize: pagination.pageSize
};
const response = await getApiData(params);
setData(response.data.list);
setPagination(prev => ({
...prev,
total: response.data.total
}));
} catch (err: any) {
setError(err.message);
showMessage('error', '获取数据失败');
} finally {
setLoading(false);
}
}, [filters, pagination.current, pagination.pageSize]);
// 初始加载
useEffect(() => {
fetchData();
}, [fetchData]);
// 处理筛选变化
const handleFilterChange = useCallback((newFilters: Filters) => {
setFilters(newFilters);
setPagination(prev => ({ ...prev, current: 1 }));
}, []);
// 处理分页变化
const handlePageChange = useCallback((page: number) => {
setPagination(prev => ({ ...prev, current: page }));
}, []);
return {
data,
loading,
error,
filters,
pagination,
handleFilterChange,
handlePageChange,
refreshData: fetchData
};
}
3. 工具函数示例
// utils/formatters.tsx
import dayjs from 'dayjs';
import { MachineryStatus } from './index.types';
/**
* 格式化农机状态
*/
export function formatMachineryStatus(status: MachineryStatus) {
const statusMap = {
'运行中': { text: '运行中', color: '#52c41a' },
'空闲中': { text: '空闲中', color: '#d9d9d9' },
'待维护': { text: '待维护', color: '#faad14' },
'已报废': { text: '已报废', color: '#ff4d4f' }
};
return statusMap[status] || { text: '未知', color: '#d9d9d9' };
}
/**
* 格式化日期
*/
export function formatDate(date: string): string {
return dayjs(date).format('YYYY-MM-DD HH:mm');
}
/**
* 格式化价格
*/
export function formatPrice(price: number): string {
return new Intl.NumberFormat('zh-CN', {
style: 'currency',
currency: 'CNY'
}).format(price);
}
4. 常量定义示例
// constants.tsx
export const MACHINERY_CATEGORIES = [
{ value: '耕地机械', label: '耕地机械' },
{ value: '播种机械', label: '播种机械' },
{ value: '收获机械', label: '收获机械' },
{ value: '植保机械', label: '植保机械' }
] as const;
export const MACHINERY_STATUS = [
{ value: '运行中', label: '运行中', color: '#52c41a' },
{ value: '空闲中', label: '空闲中', color: '#d9d9d9' },
{ value: '待维护', label: '待维护', color: '#faad14' },
{ value: '已报废', label: '已报废', color: '#ff4d4f' }
] as const;
export const PAGE_SIZE_OPTIONS = [10, 20, 50, 100] as const;
export const DEFAULT_PAGE_SIZE = 10;
🚀 后续工作
- 继续更新剩余文档: 完成 FarmingOperation 和其他模块的文档更新
- 更新开发规范: 修改 Pages目录结构与开发规范.md 中的示例
- 更新参考指南: 修改 开发者参考指南.md 中的代码示例
- 创建代码片段: 更新 VS Code 代码片段为 TypeScript 版本
✨ 总结
通过将 JavaScript 文件改为 TypeScript 文件,我们显著提高了代码的类型安全性,减少了运行时错误,并提供了更好的开发体验。这是现代 React 开发的最佳实践,特别适合大型企业级应用的开发。