Uniapp 10 分钟做一个新闻列表页:下拉刷新 + 上拉加载 + 跳转详情

核心思路
  1. 使用<scroll-view>组件实现滚动容器
  2. 绑定@refresherrefresh@scrolltolower事件
  3. 通过uni.navigateTo实现页面跳转

完整代码实现
<template>
  <view>
    <!-- 下拉刷新区域 -->
    <scroll-view 
      scroll-y 
      :refresher-enabled="true"
      :refresher-triggered="triggered"
      @refresherrefresh="onRefresh"
      @scrolltolower="onReachBottom"
      style="height: 100vh"
    >
      <!-- 新闻列表 -->
      <view v-for="(item, index) in newsList" :key="index" class="news-item" @click="goDetail(item.id)">
        <image :src="item.cover" mode="aspectFill" class="cover" />
        <view class="content">
          <text class="title">{{ item.title }}</text>
          <text class="time">{{ item.time }}</text>
        </view>
      </view>
      
      <!-- 加载提示 -->
      <view v-if="loading" class="loading">加载中...</view>
      <view v-if="noMore" class="no-more">没有更多了</view>
    </scroll-view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      triggered: false,    // 下拉刷新状态
      loading: false,      // 加载状态
      noMore: false,       // 无更多数据
      page: 1,             // 当前页码
      pageSize: 10,        // 每页条数
      newsList: []         // 新闻数据
    }
  },
  mounted() {
    this.getNewsList()
  },
  methods: {
    // 获取新闻数据
    async getNewsList() {
      this.loading = true
      
      // 模拟API请求
      const mockData = Array.from({length: this.pageSize}, (_, i) => ({
        id: i + (this.page-1)*this.pageSize,
        title: `新闻标题${i + (this.page-1)*this.pageSize + 1}`,
        cover: "/static/logo.png",  // 替换为实际图片路径
        time: "2023-06-01"
      }))
      
      // 拼接数据
      if(this.page === 1) {
        this.newsList = mockData
      } else {
        this.newsList = [...this.newsList, ...mockData]
      }
      
      // 模拟网络延迟
      await new Promise(resolve => setTimeout(resolve, 800))
      
      this.loading = false
      this.triggered = false
      this.noMore = this.page > 2  // 模拟第3页无数据
    },
    
    // 下拉刷新
    onRefresh() {
      this.triggered = true
      this.page = 1
      this.noMore = false
      this.getNewsList()
    },
    
    // 上拉加载
    onReachBottom() {
      if(this.loading || this.noMore) return
      this.page++
      this.getNewsList()
    },
    
    // 跳转详情页
    goDetail(id) {
      uni.navigateTo({
        url: `/pages/news-detail/news-detail?id=${id}`
      })
    }
  }
}
</script>

<style scoped>
.news-item {
  display: flex;
  padding: 20rpx;
  border-bottom: 1rpx solid #eee;
}

.cover {
  width: 200rpx;
  height: 150rpx;
  border-radius: 8rpx;
}

.content {
  flex: 1;
  padding-left: 20rpx;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.title {
  font-size: 32rpx;
  color: #333;
  line-height: 1.4;
}

.time {
  font-size: 24rpx;
  color: #999;
}

.loading, .no-more {
  text-align: center;
  padding: 20rpx;
  color: #999;
  font-size: 28rpx;
}
</style>


关键功能说明
  1. 下拉刷新

    • 设置:refresher-enabled="true"
    • 监听@refresherrefresh事件
    • 重置页码并重新加载数据
  2. 上拉加载

    • 监听@scrolltolower事件
    • 页码+1并追加数据
    • 通过noMore标志控制底部提示
  3. 跳转详情

    • 使用uni.navigateTo跳转
    • 传递新闻ID参数:url: /pages/news-detail/news-detail?id=${id}
  4. 数据模拟

    • 使用mockData模拟API返回
    • 通过setTimeout模拟网络延迟
    • 实际开发替换为uni.request

优化建议(后续扩展)
  1. 添加骨架屏加载动画
  2. 实现网络错误重试机制
  3. 添加图片懒加载功能
  4. 使用Vuex管理全局状态
  5. 增加分类筛选功能

提示:在详情页通过onLoad(options)接收参数:

export default {
  onLoad(options) {
    console.log('新闻ID:', options.id)
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值