核心思路
- 使用
<scroll-view>组件实现滚动容器 - 绑定
@refresherrefresh和@scrolltolower事件 - 通过
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>
关键功能说明
-
下拉刷新
- 设置
:refresher-enabled="true" - 监听
@refresherrefresh事件 - 重置页码并重新加载数据
- 设置
-
上拉加载
- 监听
@scrolltolower事件 - 页码+1并追加数据
- 通过
noMore标志控制底部提示
- 监听
-
跳转详情
- 使用
uni.navigateTo跳转 - 传递新闻ID参数:
url: /pages/news-detail/news-detail?id=${id}
- 使用
-
数据模拟
- 使用
mockData模拟API返回 - 通过
setTimeout模拟网络延迟 - 实际开发替换为
uni.request
- 使用
优化建议(后续扩展)
- 添加骨架屏加载动画
- 实现网络错误重试机制
- 添加图片懒加载功能
- 使用Vuex管理全局状态
- 增加分类筛选功能
提示:在详情页通过
onLoad(options)接收参数:export default { onLoad(options) { console.log('新闻ID:', options.id) } }
2257

被折叠的 条评论
为什么被折叠?



