更新记录

1.0.2(2025-11-19) 下载此版本

v1.0.2 (2025-11-19)

  • ✨ 新增Tab下划线指示器,跟随选中标签流畅滑动

1.0.1(2025-08-05) 下载此版本

v1.0.1 (2025-08-05)

✨ 新功能

  • 新增tabs横向滚动支持,当标签数量过多时可以左右滑动查看
  • 优化tab项布局,每个tab都有最小宽度保证,避免内容被压缩

**

1.0.0(2025-08-01) 下载此版本

v1.0.0 (2025-07-30)

  • 发布内容列表组件
  • 支持多标签页切换功能
  • 集成下拉刷新和上拉加载更多
  • 内置精美的卡片式内容展示
  • 支持内容点击事件
  • 提供切换动画效果
  • 包含加载状态和空数据提示
  • 支持自定义标签页配置
  • 内置模拟数据便于测试
查看更多

平台兼容性

uni-app(3.6.14)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 快应用-华为 快应用-联盟

其他

多语言 暗黑模式 宽屏模式

ContentList 内容列表组件

一个支持多tab切换的内容展示组件,适用于推荐、美食、旅游、宠物、培训等不同类型的内容展示。

版本历史

v1.0.2 (2025-11-19)

  • ✨ 新增Tab下划线指示器,跟随选中标签流畅滑动
  • 🎨 实现骨架屏加载效果,提升用户体验
  • ❤️ 优化点赞交互,支持点击切换点赞状态
  • 🎬 添加点赞动画效果,视觉反馈更丰富
  • 📱 Tab自动居中显示,选中标签始终可见
  • 🔍 新增搜索功能,支持标题和描述的关键词搜索
  • 📊 新增筛选排序功能,支持按热度/时间/点赞数排序
  • 🖼️ 实现图片懒加载,优化性能和流量消耗
  • 📤 新增分享功能,兼容H5/微信小程序/App
  • ⭐ 新增收藏功能,支持收藏状态管理
  • 🔍 新增长按图片预览大图功能
  • 💾 支持保存图片到相册(多端兼容)

v1.0.1

  • 新增tabs横向滚动支持,当标签数量过多时可以左右滑动查看
  • 优化tab项布局,每个tab都有最小宽度保证,避免内容被压缩

v1.0.0

  • 发布内容列表组件
  • 支持多标签页切换功能
  • 集成下拉刷新和上拉加载更多
  • 内置精美的卡片式内容展示
  • 支持内容点击事件
  • 提供切换动画效果
  • 包含加载状态和空数据提示
  • 支持自定义标签页配置
  • 内置模拟数据便于测试

功能特性

  • 📱 响应式设计,适配移动端
  • 🎨 精美的UI设计和流畅的动画效果
  • 🔄 支持下拉刷新和上拉加载更多
  • 🏷️ 多种内容分类标签样式
  • ❤️ 支持点赞和浏览数据展示,可交互点赞
  • 📊 内置丰富的模拟数据
  • 👆 tabs支持左右滑动,适配多标签场景
  • 🎯 Tab下划线指示器,视觉反馈更清晰
  • ⏳ 骨架屏加载,减少等待焦虑
  • 🔍 关键词搜索功能,快速查找内容
  • 📊 多维度排序,支持热度/时间/点赞排序
  • 🖼️ 图片懒加载,节省流量提升性能
  • 📤 分享功能,兼容多平台
  • ⭐ 收藏功能,记录喜欢的内容
  • 🔍 长按预览大图,支持保存到相册

使用方式

<template>
  <view>
    <content-list 
      :tabs-config="tabsConfig"
      :list-data="listData"
      :loading="loading"
      :enable-search="true"
      :enable-filter="true"
      :enable-share="true"
      :enable-collect="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' }
        // 支持更多标签,如:
        // { name: '摄影', key: 'photography' },
        // { name: '健身', key: 'fitness' },
        // { name: '音乐', key: 'music' },
        // { name: '读书', key: 'reading' }
        // tabs过多时会自动支持左右滑动
      ],
      listData: {},
      loading: false
    }
  },
  methods: {
    handleItemClick(item) {
      console.log('点击了内容:', item)
    },
    handleLikeItem(item) {
      console.log('点赞了内容:', item)
    },
    handleCollectItem({ item, isCollected }) {
      console.log('收藏操作:', item, isCollected)
      // 可以在这里调用API保存收藏状态
    },
    handleShareItem(item) {
      console.log('分享内容:', item)
      // 微信小程序可以在这里触发分享
      // #ifdef MP-WEIXIN
      uni.showShareMenu({
        withShareTicket: true
      })
      // #endif
    },
    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 {
        // 模拟API请求
        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) {
      // 模拟API请求
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve({
            data: [
              // 你的数据...
            ]
          })
        }, 800)
      })
    }
  }
}
</script>

Props

参数 说明 类型 默认值
tabsConfig tab配置数组 Array 见下方默认配置
listData 外部传入的列表数据 Object {}
loading 加载状态 Boolean true
enableSearch 是否启用搜索功能 Boolean false
enableFilter 是否启用筛选排序功能 Boolean false
enableShare 是否启用分享功能 Boolean false
enableCollect 是否启用收藏功能 Boolean false

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 }
load-data 初始加载数据时触发 { tabKey, page }
refresh 下拉刷新时触发 { tabKey, page }
load-more 上拉加载更多时触发 { tabKey, page }

数据结构

内容项数据结构

{
  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: ***         // 时间戳(用于排序,可选)
}

重要提示: 如果启用了点赞、收藏、分享功能,请确保数据中包含 isLikedisCollectedlikeAnimatingcollectAnimatingshareAnimating 等字段的初始值,避免运行时警告。

内置分类样式

组件支持以下几种分类,每种分类都有对应的颜色主题:

  • recommend - 推荐 (红色渐变)
  • food - 美食 (橙色渐变)
  • travel - 旅游 (绿色渐变)
  • pet - 宠物 (蓝色渐变)
  • training - 培训 (紫色渐变)

注意事项

  1. 如果不传入 listData,组件会使用内置的模拟数据
  2. 组件采用 rpx 单位,适配不同屏幕尺寸
  3. 图片地址需要是有效的网络地址或本地资源路径
  4. 组件内置了下拉刷新和上拉加载功能,适合数据较多的场景
  5. tabs支持横向滚动,当标签数量过多时可以左右滑动查看所有标签
  6. 每个tab都有最小宽度保证,不会因为标签过多而被压缩

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

本插件不采集任何数据,所有展示数据均为本地模拟数据。如需对接真实数据源,开发者可自行修改数据接口。

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议