|
|
@@ -0,0 +1,249 @@
|
|
|
+# 移动端页面加载问题修复方案
|
|
|
+
|
|
|
+## 问题诊断
|
|
|
+
|
|
|
+经过分析,发现移动端页面存在以下加载问题:
|
|
|
+
|
|
|
+### 1. 路由配置问题
|
|
|
+- 首页路由配置为根路径 `/`,但底部导航栏的 tab 配置存在潜在的匹配冲突
|
|
|
+- 轮播图和导航按钮的路由跳转可能存在空路径问题
|
|
|
+
|
|
|
+### 2. 图片加载问题
|
|
|
+- 使用了外部随机图片服务 `https://picsum.photos/`,在网络不稳定时会加载失败
|
|
|
+- 缺少图片加载失败时的备用方案
|
|
|
+
|
|
|
+### 3. 滚动行为问题
|
|
|
+- 轮播图区域缺少正确的滑动行为
|
|
|
+- 页面滚动可能不够流畅
|
|
|
+
|
|
|
+### 4. 性能优化问题
|
|
|
+- 缺少图片懒加载
|
|
|
+- 缺少错误边界处理
|
|
|
+
|
|
|
+## 修复方案
|
|
|
+
|
|
|
+### 1. 路由配置修复
|
|
|
+
|
|
|
+#### 修改 src/client/mobile/routes.tsx
|
|
|
+```typescript
|
|
|
+// 确保路由路径与底部导航栏匹配
|
|
|
+const router = createBrowserRouter([
|
|
|
+ {
|
|
|
+ path: '/',
|
|
|
+ element: <MobileLayout tabs={silverPlatformTabs} />,
|
|
|
+ children: [
|
|
|
+ {
|
|
|
+ index: true,
|
|
|
+ element: <Navigate to="/home" replace /> // 重定向到/home
|
|
|
+ },
|
|
|
+ {
|
|
|
+ path: 'home',
|
|
|
+ element: <HomePage />
|
|
|
+ },
|
|
|
+ // ... 其他路由保持不变
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ // ... 其他配置
|
|
|
+]);
|
|
|
+```
|
|
|
+
|
|
|
+#### 修改 src/client/mobile/components/BottomTabBar.tsx
|
|
|
+```typescript
|
|
|
+// 更新银龄平台底部导航配置
|
|
|
+export const silverPlatformTabs: TabItem[] = [
|
|
|
+ { id: 'home', name: '首页', icon: '🏠', path: '/home' }, // 改为/home
|
|
|
+ { id: 'silver-jobs', name: '银龄岗', icon: '💼', path: '/silver-jobs' },
|
|
|
+ { id: 'publish', name: '发布', icon: '➕', path: '/publish' },
|
|
|
+ { id: 'silver-talents', name: '银龄库', icon: '👥', path: '/silver-talents' },
|
|
|
+ { id: 'profile', name: '个人中心', icon: '👤', path: '/profile' }
|
|
|
+];
|
|
|
+```
|
|
|
+
|
|
|
+### 2. 图片加载优化
|
|
|
+
|
|
|
+#### 修改 src/client/mobile/pages/HomePage.tsx
|
|
|
+添加图片加载状态和错误处理:
|
|
|
+
|
|
|
+```typescript
|
|
|
+import React, { useState, useEffect } from 'react';
|
|
|
+
|
|
|
+// 添加图片加载组件
|
|
|
+const LazyImage: React.FC<{
|
|
|
+ src: string;
|
|
|
+ alt: string;
|
|
|
+ className?: string;
|
|
|
+ fallback?: string;
|
|
|
+}> = ({ src, alt, className, fallback = '/placeholder-image.jpg' }) => {
|
|
|
+ const [imageSrc, setImageSrc] = useState(fallback);
|
|
|
+ const [isLoading, setIsLoading] = useState(true);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ const img = new Image();
|
|
|
+ img.src = src;
|
|
|
+ img.onload = () => {
|
|
|
+ setImageSrc(src);
|
|
|
+ setIsLoading(false);
|
|
|
+ };
|
|
|
+ img.onerror = () => {
|
|
|
+ setImageSrc(fallback);
|
|
|
+ setIsLoading(false);
|
|
|
+ };
|
|
|
+ }, [src]);
|
|
|
+
|
|
|
+ return (
|
|
|
+ <img
|
|
|
+ src={imageSrc}
|
|
|
+ alt={alt}
|
|
|
+ className={`${className} ${isLoading ? 'animate-pulse bg-gray-200' : ''}`}
|
|
|
+ />
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+// 更新轮播图组件
|
|
|
+const carouselItems = [
|
|
|
+ {
|
|
|
+ id: 1,
|
|
|
+ title: '银龄智慧平台上线啦',
|
|
|
+ description: '为银龄群体打造的专业服务平台',
|
|
|
+ image: '/images/banner1.jpg', // 使用本地图片
|
|
|
+ fallbackImage: '/images/placeholder-banner.jpg',
|
|
|
+ link: '/home'
|
|
|
+ },
|
|
|
+ // ... 其他项目
|
|
|
+];
|
|
|
+```
|
|
|
+
|
|
|
+### 3. 滚动行为优化
|
|
|
+
|
|
|
+#### 添加滚动容器样式
|
|
|
+```typescript
|
|
|
+// 在轮播图区域添加平滑滚动
|
|
|
+<div className="relative bg-white overflow-hidden">
|
|
|
+ <div className="aspect-w-16 aspect-h-9">
|
|
|
+ <div className="flex overflow-x-auto snap-x snap-mandatory scroll-smooth">
|
|
|
+ {carouselItems.map((item) => (
|
|
|
+ <div
|
|
|
+ key={item.id}
|
|
|
+ className="snap-center w-full flex-shrink-0 relative cursor-pointer"
|
|
|
+ onClick={() => navigate(item.link)}
|
|
|
+ >
|
|
|
+ <LazyImage
|
|
|
+ src={item.image}
|
|
|
+ fallback={item.fallbackImage}
|
|
|
+ alt={item.title}
|
|
|
+ className="w-full h-48 object-cover"
|
|
|
+ />
|
|
|
+ {/* ... 其他内容 */}
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</div>
|
|
|
+```
|
|
|
+
|
|
|
+### 4. 错误边界添加
|
|
|
+
|
|
|
+#### 创建 ErrorBoundary 组件
|
|
|
+```typescript
|
|
|
+// src/client/mobile/components/ErrorBoundary.tsx
|
|
|
+import React from 'react';
|
|
|
+
|
|
|
+interface ErrorBoundaryState {
|
|
|
+ hasError: boolean;
|
|
|
+ error: Error | null;
|
|
|
+}
|
|
|
+
|
|
|
+export class ErrorBoundary extends React.Component<
|
|
|
+ { children: React.ReactNode },
|
|
|
+ ErrorBoundaryState
|
|
|
+> {
|
|
|
+ constructor(props: any) {
|
|
|
+ super(props);
|
|
|
+ this.state = { hasError: false, error: null };
|
|
|
+ }
|
|
|
+
|
|
|
+ static getDerivedStateFromError(error: Error) {
|
|
|
+ return { hasError: true, error };
|
|
|
+ }
|
|
|
+
|
|
|
+ componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
|
|
|
+ console.error('Error caught by boundary:', error, errorInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ render() {
|
|
|
+ if (this.state.hasError) {
|
|
|
+ return (
|
|
|
+ <div className="min-h-screen flex items-center justify-center bg-gray-50">
|
|
|
+ <div className="text-center">
|
|
|
+ <h2 className="text-2xl font-bold text-gray-900 mb-4">
|
|
|
+ 页面加载失败
|
|
|
+ </h2>
|
|
|
+ <p className="text-gray-600 mb-4">
|
|
|
+ {this.state.error?.message || '请刷新页面重试'}
|
|
|
+ </p>
|
|
|
+ <button
|
|
|
+ onClick={() => window.location.reload()}
|
|
|
+ className="bg-blue-500 text-white px-4 py-2 rounded"
|
|
|
+ >
|
|
|
+ 刷新页面
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ return this.props.children;
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 5. 性能优化
|
|
|
+
|
|
|
+#### 添加图片预加载
|
|
|
+```typescript
|
|
|
+// 在组件挂载时预加载关键图片
|
|
|
+useEffect(() => {
|
|
|
+ carouselItems.forEach(item => {
|
|
|
+ const img = new Image();
|
|
|
+ img.src = item.image;
|
|
|
+ });
|
|
|
+}, []);
|
|
|
+```
|
|
|
+
|
|
|
+### 6. 加载状态优化
|
|
|
+
|
|
|
+#### 添加骨架屏
|
|
|
+```typescript
|
|
|
+// 添加加载骨架组件
|
|
|
+const SkeletonLoader: React.FC = () => (
|
|
|
+ <div className="animate-pulse">
|
|
|
+ <div className="bg-gray-300 h-48 w-full mb-4"></div>
|
|
|
+ <div className="grid grid-cols-3 gap-4 mb-4">
|
|
|
+ {[...Array(6)].map((_, i) => (
|
|
|
+ <div key={i} className="flex flex-col items-center">
|
|
|
+ <div className="bg-gray-300 w-12 h-12 rounded-full mb-2"></div>
|
|
|
+ <div className="bg-gray-300 h-4 w-16 rounded"></div>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+);
|
|
|
+```
|
|
|
+
|
|
|
+## 实施步骤
|
|
|
+
|
|
|
+1. **第一步**:修复路由配置,确保路径匹配
|
|
|
+2. **第二步**:添加图片加载优化和错误处理
|
|
|
+3. **第三步**:添加滚动行为优化
|
|
|
+4. **第四步**:添加错误边界和加载状态
|
|
|
+5. **第五步**:测试和验证修复效果
|
|
|
+
|
|
|
+## 测试验证
|
|
|
+
|
|
|
+修复后需要验证:
|
|
|
+- [ ] 首页正常加载
|
|
|
+- [ ] 底部导航栏正常工作
|
|
|
+- [ ] 轮播图正常显示和滑动
|
|
|
+- [ ] 图片加载失败时有备用方案
|
|
|
+- [ ] 路由跳转正常
|
|
|
+- [ ] 页面响应式设计正常工作
|