# taro-page-virtual-scroll **Repository Path**: ocean_vane/taro-page-virtual-scroll ## Basic Information - **Project Name**: taro-page-virtual-scroll - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-02 - **Last Updated**: 2025-12-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Taro 页面级虚拟滚动 高性能的 Taro 虚拟滚动解决方案,专为海量评论列表、动态高度内容等场景优化。 ## ✨ 核心特性 - **虚拟滚动**: 只渲染可见区域,支持数千项列表 - **动态高度**: 智能测量与回填,支持不规则高度 - **分层评论**: 支持主评论+子评论的多层级结构 - **智能加载**: 分页、分批、加载更多等多种模式 - **性能优化**: EMA 算法、预测缓冲、批量测量 - **Taro 兼容**: 微信、支付宝、字节等小程序 ## 🚀 快速开始 ### 安装依赖 ```bash npm install ``` ### 启动 Mock 服务 ```bash npm run mock:dev ``` ### 开发模式 ```bash # 微信小程序 npm run dev:weapp # 支付宝小程序 npm run dev:alipay # 其他平台参考 package.json scripts ``` ### 生产构建 ```bash npm run build:weapp ``` ## 📚 API 接口 ### Mock 服务地址 ``` http://127.0.0.1:3001 ``` ### 主要接口 #### 获取主评论列表 ```http GET /comments?_page=1&_limit=20 ``` **参数**: - `_page` - 页码(从 1 开始) - `_limit` - 每页数量 - `_sort` - 排序字段(如 `likes`) - `_order` - 排序顺序(`asc`/`desc`) #### 获取子评论 ```http GET /replies?parentId=1&_page=1&_limit=40 ``` **参数**: - `parentId` - 父评论 ID(必需) - `_page` - 页码 - `_limit` - 每页数量 ### 数据格式 ```typescript interface CommentNode { id: number; // 评论ID parentId: null | number; // 父评论ID(null=主评论) username: string; // 用户名 avatar: string; // 头像URL content: string; // 评论内容 timestamp: number; // 时间戳 displayTime: string; // 显示时间(如"2天前") likes: number; // 点赞数 depth: number; // 层级(0=主评论) images: string[]; // 图片URL数组 replies: CommentNode[]; // 子评论数组 replyCount: number; // 子评论总数 hasMoreReplies: boolean; // 是否有更多子评论 isExpanded: boolean; // 是否已展开 isLoading: boolean; // 是否正在加载 replyLoadState: string; // 加载状态 replyOffset: number; // 已加载子评论数 replyBatchSize: number; // 每批加载数 } ``` ## 💻 使用示例 ### 基础使用 ```tsx import { PageVirtualList } from "@/components/virtual-page-scroll"; import { getComments } from "@/apis/comment"; export default function Page() { const [items, setItems] = useState([]); useEffect(() => { loadData(); }, []); const loadData = async () => { const comments = await getComments(1, 100); const virtualItems = comments.map((c) => ({ key: String(c.id), data: c, })); setItems(virtualItems); }; return ( } config={{ defaultItemHeight: 200, bufferSize: 800, }} /> ); } ``` ### 获取评论数据 ```tsx import { getComments, getReplies, getAllReplies } from "@/apis/comment"; // 获取主评论(分页) const comments = await getComments(1, 20); // 获取子评论(分页) const replies = await getReplies(commentId, 1, 40); // 获取所有子评论 const allReplies = await getAllReplies(commentId); ``` ### 展开/折叠子评论 ```tsx import { useToggleReplies } from "@/pages/index/hooks/useToggleReplies"; const { toggleReplies } = useToggleReplies(); const handleToggle = async (comment) => { const result = await toggleReplies( commentTree, comment.id, comment.replyBatchSize ); setCommentTree(result.updatedTree); }; ``` ## ⚙️ 虚拟列表配置 ```typescript interface VirtualListConfig { // 默认项高度(像素) defaultItemHeight?: number; // 默认:100 // 缓冲区大小(像素) bufferSize?: number; // 默认:800 // 最少渲染条目数 minRenderCount?: number; // 默认:12 // 最大单帧测量数 maxMeasurePerFrame?: number; // 默认:10 // 高度估算偏差系数 estimateBiasFactor?: number; // 默认:1.2 // 指数滑动平均系数 emaAlpha?: number; // 默认:0.3 // 调试日志 enableDebugLog?: boolean; // 默认:false } ``` ## ⚠️ 注意事项 ### 1. 数据规范化 确保评论数据包含所有必需字段,特别是: ```typescript { id: number, // 不能是字符串 content: string, // 不能是 null replyCount: number, // 不能是字符串 timestamp: number, // 毫秒级时间戳 displayTime: string, // 格式化后的时间 } ``` ### 2. 性能优化 - **列表项高度**: 尽量保持一致性 - **渲染复杂度**: 保持简单,避免复杂计算 - **事件处理**: 避免在项中进行重量级状态更新 - **分页加载**: 大数据量时分页而不是一次性加载 ### 3. Mock 服务 - **启动位置**: 在项目根目录运行 - **端口**: 3001(确保未被占用) - **CORS**: 已启用,支持跨域 - **重启**: 修改 db.json 后需重启服务 ```bash # 检查服务 curl http://127.0.0.1:3001/comments # 重启 npm run mock:dev ``` ### 4. 图片加载 - 自动支持懒加载 - 确保 URL 可访问 - 预估高度时考虑图片占用空间 - 虚拟滚动中图片加载状态会保留 ## 🐛 常见问题 ### 列表卡顿? 1. 增加 `defaultItemHeight` 准确性 2. 减少 `bufferSize` 值 3. 简化列表项渲染 4. 检查浏览器性能 ### 高度计算不准? 1. 检查 `defaultItemHeight` 设置 2. 增加 `maxMeasurePerFrame` 3. 检查异步内容(如图片) 4. 启用 `enableDebugLog` 查看日志 ### 子评论不显示? 1. 检查 Mock 服务是否运行 2. 验证 `parentId` 是否正确 3. 查看控制台网络请求 4. 检查 `replies` 字段初始化 ## 📂 项目结构 ``` src/ ├── apis/ │ └── comment.ts # 评论 API ├── components/ │ └── virtual-page-scroll/ # 虚拟滚动核心 │ ├── PageVirtualList.tsx # 主组件 │ ├── heightManager.ts # 高度管理 │ ├── visibilityManager.ts # 可视区管理 │ ├── useScrollManager.ts # 滚动 Hook │ ├── types.ts # 类型定义 │ └── constants.ts # 常量配置 └── pages/ └── index/ # 评论页面 ├── index.tsx ├── types.ts ├── hooks/ # 自定义 Hooks └── components/ # 页面组件 mock/ ├── express-server.js # Express 服务器 ├── db.json # 数据库 └── init.js # 初始化脚本 ``` ## 📖 详细文档 参考 `README_DETAILED.md` 获取完整文档,包括: - 详细的 API 文档 - 高级配置指南 - 性能优化技巧 - 核心算法说明 - 更多常见问题解答 ## 🔧 技术栈 - **框架**: [Taro 4.1.8](https://taro.zone/) - **UI**: React 18.x - **类型**: TypeScript 5.x - **测试数据**: Express Mock Server - **样式**: CSS3 ## 📊 性能指标 | 指标 | 数据量 | 表现 | | -------- | ------- | --------- | | 首屏渲染 | 100 项 | ~200ms | | 首屏渲染 | 1000 项 | ~300ms | | 滚动帧率 | 任意 | 55-60 FPS | | 内存占用 | 1000 项 | ~20MB | ## 📞 获取帮助 - 📖 查看详细文档:`README_DETAILED.md` - 🐛 查看常见问题:本文件下方 - 💬 Taro 官方社区 ## 📄 许可证 MIT --- **更新时间**: 2025 年 12 月 **项目版本**: 1.0.0