unicloud21-小案例7 onReachB0ttom触底翻页功能实现

82 阅读2分钟

根据时间戳排序

之前的字段中存了时间戳,这里通过时间戳进行降序排列,将后添加的新闻展示在上面

index.js | art_get_all

'use strict';
const db=uniCloud.database();
exports.main = async (event, context) => {
	return await db.collection("article").orderBy("posttime","desc").get();
};

现在确实实现了通过时间戳进行降序排列 image.png

翻页 每页展示8条数据

index.js | art_get_all

'use strict';
const db=uniCloud.database();
exports.main = async (event, context) => {
	return await db.collection("article").limit(8).orderBy("posttime","desc").get();
};

触底加载更多

使用uni云数据库提供的skip方法开发翻页功能 通过前端传递的数据确定页数,skip接收这个参数做分页功能 index.js | art_get_all

'use strict';
const db=uniCloud.database();
exports.main = async (event, context) => {
  // 将前端传递的页数解构出来,传递给skip、
  // 因为skip可能存在没有传的情况,所以给一个初始值为0
  let {skip=0} = event;
	return await db.collection("article").limit(8).skip(skip).orderBy("posttime","desc").get();
};

然后在首页传递数据给skip: 这里写5就表示跳过前5条,从第6条数据开始传

<script>
	export default {
		data() {
			return {
        listArr:[]
			}
		},
		onLoad() {
      this.getData()
		},
		methods: {
      // 获取数据库列表
      getData(){
        uniCloud.callFunction({
          name:"art_get_all",
          data:{
            skip:5
          }
        }).then(res=>{
          console.log(res);
          this.listArr = res.result.data
        })
      },
      // 点击按钮跳转到新增页面
      goAdd(){
        uni.navigateTo({
          url:"/pages/add/add"
        })
      }
		}
	}
</script>

通过data携带给skip的参数是5,就跳过了数据库中的前5条数据,下图是从第6条数据开始展示的 image.png

因此,首页请求数据这里传的这个skip值应该是一个变量,变量的值应该来自用户有没有上拉刷新

这里skip的值,就是已经刷新的数据条数,就是上面data中保存的listArr

listArr初始值是0,而上面在云函数中使用limit订好了每次取8条数据,所以,这里第一次刷新就应该是8条

<script>
	export default {
		data() {
			return {
        listArr:[]
			}
		},
		onLoad() {
      this.getData()
		},
		methods: {
      // 获取数据库列表
      getData(){
        uniCloud.callFunction({
          name:"art_get_all",
          data:{
            skip:this.listArr.length
          }
        }).then(res=>{
          console.log(res);
          this.listArr = res.result.data
        })
      },
      // 点击按钮跳转到新增页面
      goAdd(){
        uni.navigateTo({
          url:"/pages/add/add"
        })
      }
		}
	}
</script>

触底翻页 onReachBottom

这个方法是uniapp的页面生命周期方法,文档在教程 \rightarrow 页面

onReachBottom页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据。具体见下方注意事项

在首页index.vue中使用这个方法

用这个方法刷新的数据只能刷新一次,因为值被固定成8了,怎么刷都是第二页的8条数据,因为刷新的数来源是之前固定的8次 解决办法:在请求数据时把之前请求的数据和新请求的数据拼接在一个数组里

<template>
	<view class="home">
    <view class="content">
      <view class="item" v-for="item in listArr" :key="item._id">
        <view class="text">
          <view class="title">{{item.title}}</view>
          <view class="info">
            <text>{{item.author}}</text>
            <text>{{item.posttime}}</text>
            <text>删除</text>
          </view>
        </view>
        <view class="pic">
          <image src="../../static/images/nopic.jpg" mode="aspectFill"></image>
        </view>
      </view>
    </view>
    <!-- 跳转到新增页面 -->
    <view class="goAdd" @click="goAdd">+</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
        listArr:[]
			}
		},
		onLoad() {
      this.getData()
		},
    // 页面触底事件,来自uniapp页面生命周期方法
    // 页面触底后,调用云函数获取新数据
    // 这个方法写在onload后面,这样,onload是进入页面后的第一次加载数据
     // 而这个方法是用户操作后,页面触底刷新数据
    onReachBottom() {
      this.getData()
    },
		methods: {
      // 获取数据库列表
      getData(){
        uniCloud.callFunction({
          name:"art_get_all",
          data:{
            skip:this.listArr.length
          }
        }).then(res=>{
          console.log(res);
          // 老的列表数据,就是之前获取到前端的数据
          let oldList = this.listArr;
          // 将新获取的数据和之前获取的数据拼在一个数组里
          // 用展开符才能把他们放在一个一维数组里,否则就是二维数组了
          let nsList = [...oldList, ...res.result.data]
          this.listArr = nsList
        })
      },
      // 点击按钮跳转到新增页面
      goAdd(){
        uni.navigateTo({
          url:"/pages/add/add"
        })
      }
		}
	}
</script>

<!-- 在Vue文件中的style标签上有一个特殊的属性,scoped。当一个style标签拥有scoped属性时候,它的css样式只能用于当前的Vue组件,可以使组件的样式不相互污染。如果一个项目的所有style标签都加上了scoped属性,相当于实现了样式的模块化。 -->
<style lang="scss" scoped>
	.home {
    .content {
      padding: 30rpx;
      .item {
        // 弹性布局,使文字和图片在一行显示
        display: flex;
        // 两端对齐
        justify-content: space-between;
        padding: 20rpx 0;
        border-bottom: 1rpx solid #eee;
        .text {
          flex:1;
          // 下面这三行是为了给标题和作者添加边距
          // 给文字加弹性盒模型,会使标题和作者时间显示在一行
          display: flex;
          // 使标题和作者纵向排列
          flex-direction: column;
          // 标题和作者上下两端对齐
          justify-content: space-between;
          // 使文字和图片有20的间隔
          padding-right: 20rpx;
          .title {
            font-size: 44rpx;
            color: #333;
            // 使文字对齐,没看出效果来,不知道什么用
            text-align: justify;
            // 下面是标题超出两行省略号显示
            text-overflow: -o-ellipsis-lastline;
            overflow: hidden;				//溢出内容隐藏
            text-overflow: ellipsis;		//文本溢出部分用省略号表示
            display: -webkit-box;			//特别显示模式
            -webkit-line-clamp: 2;			//行数
            line-clamp: 2;					
            -webkit-box-orient: vertical;	//盒子中内容竖直排列
          }
          .info {
            font-size: 28rpx;
            color:#888;
            // 给作者、时间部分文字间隔
            text {
              padding-right: 20rpx;
            }
          }
        }
        .pic {
          width: 260rpx;
          height: 180rpx;
          image{
            width: 100%;
            height: 100%;
          }
        }
      } 
    }
    // 给按钮写样式
    .goAdd {
      width: 120rpx;
      height: 120rpx;
      background: #2B9939;
      display: flex;
      justify-content: center;
      align-items: center;
      border-radius: 50%;
      font-size: 50rpx;
      // 盒子固定定位到右下角
      position: fixed;
      right: 60rpx;
      bottom: 100rpx;
      // 按钮阴影
      box-shadow: 0 0 20rpx rgba(43, 153, 157, 0.6);
    }
  }
</style>