我们研发开源了一款基于 Git 进行技术实战教程写作的工具,我们图雀社区的所有教程都是用这款工具写作而成,欢迎 Star 哦
如果你想快速了解如何使用,欢迎阅读我们的 教程文档哦
本文由图雀社区认证作者 测不准 使用 Tuture 写作工具写作而成,图雀社区将连载其 uni-app 结合云函数开发小程序博客系列,感谢作者的优质输出,让我们的技术世界变得更加美好😆
因为项目做的是博客demo, 首页进来想给人直观的就能看到文章,看到分类。所以想的一个是可以左右滑动,切换分类,一个是页面以列表形式,直接 list 渲染。类似掘金的样式:
- 页面的左右滑动,并自带过渡效果,直接就可以使用自带的swiper组件;
- 顶部的分类导航其实也是跟着可以左右滑动,并且跟随swiper 页面同步切换,选择也是小程序组件scroll-view,设置为左右滑动;
- 上拉加载更多:小程序有自带的生命周期
onReachBottom
, 默认距离底部50px距离,想要修改可以在页面的style 中设置onReachBottomDistance
字段 - 下拉刷新:小程序页面生命周期
onPullDownRefresh
,同时要在页面的style重配置
enablePullDownRefresh:true
开启下拉刷新;掘金的下拉刷新是安卓app的下拉样式,当你用uniapp开发应用,真机运行是可以看到如下结果。
小程序自带的下拉样式如下(原生导航条):
使用自定义导航条下拉样式如下:它会从最顶部开始出现下拉样式
很明显上面的结果不是我们想要的,常用的方式是自定义导航条下面的内容区使用scroll-view 组件,通过scroll-view监听到达顶部和到达底部,继而出发下拉和上拉。为了避免重复造轮子和瞻仰大佬的代码,咱们选择到插件市场逛一逛:最终我选择了如下插件
引入插件进行布局
- 下载插件,把如下两个文件夹复制到自己的项目中,我放到了(
/colorui/components/
),scroll有空数据时的图片记得一并引入。
大家可以自己运行下载的zip安装包,项目直接可以跑通。咱们这里不做演示,直接引入插件中的代码放入首页: (代码参考插件中的/pages/swipe-list/index.vue
)
以下代码在 /pages/home/home.vue 中
...
<view class="top-wrap"><tab id="category" :tab-data="categoryMenu" :cur-index="categoryCur" :size="80" :scroll="true" @change="toggleCategory"></tab></view>
// 这里 swiper使用的是animationfinish,当滑动完成后改变,也可以使用 change事件
<swiper :current="categoryCur" :duration="duration" @animationfinish="swipeChange">
<swiper-item v-for="(item, index) in categoryData" :key="index">
<scroll :requesting="item.requesting" :end="item.end" :empty-show="item.emptyShow" :list-count="item.listCount" :has-top="true" :refresh-size="80" @refresh="refresh" @more="more">
<view class="cells">
<view class="cell" v-for="(item, index) in item.listData" :key="index">
<view class="cell__hd"><image mode="aspectFill" :src="item.images" /></view>
<view class="cell__bd">
<view class="name">{
{ item.title }}</view>
<view class="des">{
{ item.description }}</view>
</view>
</view>
</view>
</scroll>
</swiper-item>
</swiper>
...
以下代码在 /pages/home/home.vue 中
// 用于分页
let pageStart = 0
let pageSize = 15
// 列表数据
let testData = [
{
title: '这个绝望的世界没有存在的价值,所剩的只有痛楚',
description: '思念、愿望什么的都是一场空,被这种虚幻的东西绊住脚,什么都做不到',
images: '/static/logo.png' // 这里换成自己本地的图片地址
}...]
// 引入组件, 修改路径
import Tab from '@/colorui/components/tab/index'
import Scroll from '@/colorui/components/scroll/index'
components:{
Tab, Scroll},
// 当页面存在时,只会加载一次; onShow 是每次界面显示都会触发,包括手机的屏幕关闭和唤起
onLoad() {
// 第一次进入 加载第一页的数据
this.getList('refresh', pageStart)
},
methods: {
getList(type, currentPage = 1) {
let pageData = this.getCurrentData()
pageData.requesting = true
this.setCurrentData(pageData)
uni.showNavigationBarLoading()
setTimeout(() => {
pageData.requesting = false
uni.hideNavigationBarLoading()
if (type === 'refresh') {
pageData.listData = testData
pageData.listCount = pageData.listData.length
pageData.end = false //是否已经全部加载
pageData.page = currentPage + 1
} else {
pageData.listData = pageData.listData.concat(testData)
pageData.listCount = pageData.listData.length
pageData.end = true
pageData.page = currentPage + 1
}
this.setCurrentData(pageData)
}, 100)
},
// 顶部tab切换事件
toggleCategory(e) {
this.duration = 0
setTimeout(() => {
this.categoryCur = e.index
}, 0)
},
// 页面滑动切换事件
swipeChange(e) {
this.duration = 300
setTimeout(() => {
this.categoryCur = e.detail.current
this.loadData()
}, 0)
},
// 更新页面数据
setCurrentData(pageData) {
this.categoryData[this.categoryCur