更新记录
1.0.3(2025-12-23)
下载此版本
v1.0.3 (2025-12-23) - 性能优化大版本
1.0.2(2025-11-19)
下载此版本
v1.0.2 (2025-11-19)
1.0.1(2025-08-05)
下载此版本
v1.0.1 (2025-08-05)
✨ 新功能
- 新增tabs横向滚动支持,当标签数量过多时可以左右滑动查看
- 优化tab项布局,每个tab都有最小宽度保证,避免内容被压缩
**
查看更多
平台兼容性
uni-app(3.6.15)
| Vue2 |
Vue3 |
Chrome |
Safari |
app-vue |
app-nvue |
Android |
iOS |
鸿蒙 |
| √ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
| 微信小程序 |
支付宝小程序 |
抖音小程序 |
百度小程序 |
快手小程序 |
京东小程序 |
鸿蒙元服务 |
QQ小程序 |
飞书小程序 |
小红书小程序 |
快应用-华为 |
快应用-联盟 |
| √ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
- |
√ |
√ |
其他
ContentList 内容列表组件
一个支持多tab切换的内容展示组件,适用于推荐、美食、旅游、宠物、培训等不同类型的内容展示。
版本历史
v1.0.3 (2025-12-23) - 性能优化大版本
- 🚀 虚拟列表/长列表优化:列表数据超过阈值时自动启用虚拟滚动,只渲染可视区域数据
- 📦 Tab懒加载:仅当Tab被首次访问时才加载数据,避免一次性加载全部数据
- 💾 数据缓存机制:支持内存缓存和持久化缓存,可配置过期时间
- 🖼️ 图片预加载:首屏图片优先预加载,滚动时预加载下一屏图片
- 🔄 错误重试机制:新增ErrorRetry组件,优雅处理各类错误并支持重试
- 🔧 组件拆分优化:代码从1240行拆分为多个子组件+工具模块
SearchFilterBar.vue - 搜索和筛选栏组件
TabsNav.vue - 标签导航组件
ContentItem.vue - 内容项组件
SkeletonLoader.vue - 骨架屏加载组件
ErrorRetry.vue - 错误重试组件 (新增)
share.js - 分享功能工具模块
cache.js - 数据缓存工具模块 (新增)
imagePreloader.js - 图片预加载工具模块 (新增)
- 🐛 修复Tab指示器跳动问题:改用
left 定位替代 transform,缓存位置信息
- ✨ 新增Swiper滑动切换:支持左右滑动切换tab内容,与点击tab双向同步
- 🎯 优化指示器定位:修正底部位置,贴底显示更美观
- 💫 动画优化:骨架屏仅在首次加载时显示,加载中状态增加旋转动画
- 🎛️ 新增Props:
enableSwiper - 是否启用滑动切换功能(默认true)
enableVirtualList - 是否启用虚拟列表(默认true)
virtualThreshold - 虚拟列表阈值(默认20)
enableCache - 是否启用缓存(默认true)
cacheExpireTime - 缓存过期时间(默认5分钟)
enableImagePreload - 是否启用图片预加载(默认true)
preloadImageCount - 预加载图片数量(默认5)
- 📡 新增事件:
cache-hit - 命中缓存时触发
scroll - 滚动时触发
retry - 重试时触发
- 🔧 新增方法:
setError(tabKey, errorInfo) - 设置错误状态
setLoadComplete(tabKey, hasMore) - 设置加载完成状态
getCacheStats() - 获取缓存统计
clearAllCache() - 清除所有缓存
v1.0.2 (2025-11-19)
- ✨ 新增Tab下划线指示器,跟随选中标签流畅滑动
- 🎨 实现骨架屏加载效果,提升用户体验
- ❤️ 优化点赞交互,支持点击切换点赞状态
- 🎬 添加点赞动画效果,视觉反馈更丰富
- 📱 Tab自动居中显示,选中标签始终可见
- 🔍 新增搜索功能,支持标题和描述的关键词搜索
- 📊 新增筛选排序功能,支持按热度/时间/点赞数排序
- 🖼️ 实现图片懒加载,优化性能和流量消耗
- 📤 新增分享功能,兼容H5/微信小程序/App
- ⭐ 新增收藏功能,支持收藏状态管理
- 🔍 新增长按图片预览大图功能
- 💾 支持保存图片到相册(多端兼容)
v1.0.1
- 新增tabs横向滚动支持,当标签数量过多时可以左右滑动查看
- 优化tab项布局,每个tab都有最小宽度保证,避免内容被压缩
v1.0.0
- 发布内容列表组件
- 支持多标签页切换功能
- 集成下拉刷新和上拉加载更多
- 内置精美的卡片式内容展示
- 支持内容点击事件
- 提供切换动画效果
- 包含加载状态和空数据提示
- 支持自定义标签页配置
- 内置模拟数据便于测试
功能特性
- 📱 响应式设计,适配移动端
- 🎨 精美的UI设计和流畅的动画效果
- 🔄 支持下拉刷新和上拉加载更多
- 👆 支持Swiper左右滑动切换(v1.0.3新增)
- 🏷️ 多种内容分类标签样式
- ❤️ 支持点赞和浏览数据展示,可交互点赞
- 📊 内置丰富的模拟数据
- 🎯 Tab下划线指示器,视觉反馈更清晰
- ⏳ 骨架屏加载,减少等待焦虑
- 🔍 关键词搜索功能,快速查找内容
- 📊 多维度排序,支持热度/时间/点赞排序
- 🖼️ 图片懒加载,节省流量提升性能
- 📤 分享功能,兼容多平台
- ⭐ 收藏功能,记录喜欢的内容
- 🔍 长按预览大图,支持保存到相册
- 🧩 模块化架构,代码结构清晰易维护(v1.0.3重构)
使用方式
<template>
<view>
<content-list
:tabs-config="tabsConfig"
:list-data="listData"
:loading="loading"
:enable-search="true"
:enable-filter="true"
:enable-share="true"
:enable-collect="true"
:enable-swiper="true"
@item-click="handleItemClick"
@like-item="handleLikeItem"
@collect-item="handleCollectItem"
@share-item="handleShareItem"
@search="handleSearch"
@search-confirm="handleSearchConfirm"
@sort-change="handleSortChange"
@tab-change="handleTabChange"
@load-data="handleLoadData"
@refresh="handleRefresh"
@load-more="handleLoadMore"
/>
</view>
</template>
<script>
import ContentList from '@/components/content-list-compone/index.vue'
export default {
components: {
ContentList
},
data() {
return {
tabsConfig: [
{ name: '推荐', key: 'recommend' },
{ name: '美食', key: 'latest' },
{ name: '旅游', key: 'sales' },
{ name: '宠物', key: 'price' },
{ name: '培训', key: 'popularity' }
],
listData: {},
loading: false
}
},
methods: {
handleItemClick(item) {
console.log('点击了内容:', item)
},
handleLikeItem(item) {
console.log('点赞了内容:', item)
},
handleCollectItem({ item, isCollected }) {
console.log('收藏操作:', item, isCollected)
},
handleShareItem(item) {
console.log('分享内容:', item)
},
handleSearch(keyword) {
console.log('搜索关键词:', keyword)
},
handleSearchConfirm(keyword) {
console.log('确认搜索:', keyword)
},
handleSortChange(sortValue) {
console.log('排序方式改变:', sortValue)
},
async handleTabChange({ key, page }) {
console.log('切换tab:', key, page)
await this.fetchData(key, page)
},
async handleLoadData({ tabKey, page }) {
console.log('加载数据:', tabKey, page)
await this.fetchData(tabKey, page)
},
async handleRefresh({ tabKey, page }) {
console.log('下拉刷新:', tabKey, page)
await this.fetchData(tabKey, page)
},
async handleLoadMore({ tabKey, page }) {
console.log('加载更多:', tabKey, page)
await this.fetchData(tabKey, page, true)
},
async fetchData(tabKey, page, isLoadMore = false) {
this.loading = true
try {
const response = await this.mockApiRequest(tabKey, page)
if (isLoadMore) {
this.listData[tabKey] = [...(this.listData[tabKey] || []), ...response.data]
} else {
this.listData[tabKey] = response.data
}
this.$forceUpdate()
} catch (error) {
console.error('加载失败:', error)
uni.showToast({ title: '加载失败', icon: 'none' })
} finally {
this.loading = false
}
},
mockApiRequest(tabKey, page) {
return new Promise((resolve) => {
setTimeout(() => {
resolve({
data: [/* 你的数据... */]
})
}, 800)
})
}
}
}
</script>
Props
| 参数 |
说明 |
类型 |
默认值 |
版本 |
| tabsConfig |
tab配置数组 |
Array |
见下方默认配置 |
v1.0.0 |
| listData |
外部传入的列表数据 |
Object |
{} |
v1.0.0 |
| loading |
加载状态 |
Boolean |
false |
v1.0.3 |
| enableSearch |
是否启用搜索功能 |
Boolean |
false |
v1.0.2 |
| enableFilter |
是否启用筛选排序功能 |
Boolean |
false |
v1.0.2 |
| enableShare |
是否启用分享功能 |
Boolean |
false |
v1.0.2 |
| enableCollect |
是否启用收藏功能 |
Boolean |
false |
v1.0.2 |
| enableSwiper |
是否启用滑动切换功能 |
Boolean |
true |
v1.0.3 |
| enableVirtualList |
是否启用虚拟列表 |
Boolean |
true |
v1.0.3 |
| virtualThreshold |
虚拟列表启用阈值 |
Number |
20 |
v1.0.3 |
| enableCache |
是否启用数据缓存 |
Boolean |
true |
v1.0.3 |
| cacheExpireTime |
缓存过期时间(毫秒) |
Number |
300000 |
v1.0.3 |
| enableImagePreload |
是否启用图片预加载 |
Boolean |
true |
v1.0.3 |
| preloadImageCount |
预加载图片数量 |
Number |
5 |
v1.0.3 |
tabsConfig 默认配置
[
{ name: '推荐', key: 'recommend' },
{ name: '美食', key: 'latest' },
{ name: '旅游', key: 'sales' },
{ name: '宠物', key: 'price' },
{ name: '培训', key: 'popularity' }
]
Events
| 事件名 |
说明 |
参数 |
| item-click |
点击内容项时触发 |
item: 内容项数据 |
| like-item |
点赞内容时触发 |
{ ...item, index } |
| collect-item |
收藏/取消收藏时触发 |
{ ...item, index, isCollected } |
| share-item |
点击分享时触发 |
{ ...item, index } |
| search |
搜索输入时触发(防抖300ms) |
keyword: 搜索关键词 |
| search-confirm |
确认搜索时触发 |
keyword: 搜索关键词 |
| sort-change |
排序方式改变时触发 |
sortValue: 排序值 |
| tab-change |
切换tab时触发 |
{ index, key, page, isFirstLoad } |
| load-data |
初始加载数据时触发 |
{ tabKey, page } |
| refresh |
下拉刷新时触发 |
{ tabKey, page } |
| load-more |
上拉加载更多时触发 |
{ tabKey, page } |
| cache-hit |
命中缓存时触发 |
{ tabKey, data } |
| scroll |
滚动时触发 |
{ scrollTop, tabKey } |
| retry |
错误重试时触发 |
{ tabKey, page } |
Methods (可通过ref调用)
| 方法名 |
说明 |
参数 |
| setError |
设置错误状态 |
(tabKey, errorInfo) |
| setLoadComplete |
设置加载完成状态 |
(tabKey, hasMore) |
| getCacheStats |
获取缓存统计信息 |
无 |
| clearAllCache |
清除所有缓存 |
无 |
errorInfo 结构
{
type: 'network', // 'network' | 'server' | 'empty' | 'timeout' | 'custom'
message: '自定义错误信息' // 可选
}
组件架构
v1.0.3 模块化重构
components/content-list-compone/
├── index.vue # 主组件 (~800行)
├── components/
│ ├── SearchFilterBar.vue # 搜索和筛选栏 (~180行)
│ ├── TabsNav.vue # Tab导航 (~130行)
│ ├── ContentItem.vue # 内容项卡片 (~300行)
│ ├── SkeletonLoader.vue # 骨架屏 (~100行)
│ └── ErrorRetry.vue # 错误重试 (~200行) [NEW]
└── utils/
├── share.js # 分享工具 (~180行)
├── cache.js # 数据缓存 (~150行) [NEW]
└── imagePreloader.js # 图片预加载 (~100行) [NEW]
数据结构
内容项数据结构
{
tag: '热门推荐', // 分类标签文本
category: 'recommend', // 分类类型,影响标签样式
title: '内容标题', // 内容标题
description: '内容描述...', // 内容描述
image: 'https://...', // 主图片地址
tags: ['标签1', '标签2'], // 标签数组
authorAvatar: 'https://...', // 作者头像
authorName: '作者名称', // 作者名称
likes: 1520, // 点赞数
views: 8800, // 浏览数
isLiked: false, // 是否已点赞(必须初始化)
isCollected: false, // 是否已收藏(必须初始化)
likeAnimating: false, // 点赞动画状态(必须初始化)
collectAnimating: false, // 收藏动画状态(必须初始化)
shareAnimating: false, // 分享动画状态(必须初始化)
timestamp: 1234567890 // 时间戳(用于排序,可选)
}
重要提示: 如果启用了点赞、收藏、分享功能,请确保数据中包含 isLiked、isCollected、likeAnimating、collectAnimating、shareAnimating 等字段的初始值,避免运行时警告。
内置分类样式
组件支持以下几种分类,每种分类都有对应的颜色主题:
recommend - 推荐 (红色渐变)
food - 美食 (橙色渐变)
travel - 旅游 (绿色渐变)
pet - 宠物 (蓝色渐变)
training - 培训 (紫色渐变)
注意事项
- 如果不传入
listData,组件会使用内置的模拟数据
- 组件采用 rpx 单位,适配不同屏幕尺寸
- 图片地址需要是有效的网络地址或本地资源路径
- 组件内置了下拉刷新和上拉加载功能,适合数据较多的场景
- tabs支持横向滚动,当标签数量过多时可以左右滑动查看所有标签
- 每个tab都有最小宽度保证,不会因为标签过多而被压缩
- v1.0.3: 启用
enableSwiper 后,支持左右滑动切换tab内容
- v1.0.3: 组件已拆分为多个子组件,便于维护和二次开发
性能优化建议
- 使用图片懒加载减少首屏加载时间
- 开启骨架屏提升用户体验
- 合理设置每页数据量(建议10-20条)
- 大数据量场景建议启用虚拟列表(待v1.1.0支持)
- 图片建议使用CDN并压缩