36-onReachBottom触底加载更多翻页效果

247 阅读3分钟

文档在uniapp官网--教程--页面中的页面声明周期中,有一个onPullDownRefresh方法,用于监听用户下拉动作,下拉刷新

还有一个上拉触底onReachBottom方法

这两个方法都能实现,这里用的是上拉触底,下拉刷新更简单,在onload方法下面写这个方法

onLoad() {
      this.getNavData()
      this.getNewsData()
		},
    onReachBottom(){
      console.log("到底部了");
    },
methods: {

image.png

只要页面一拉到底部,这个方法就会被触发 image.png

前面写的网络数据获取方法还得改,还得加一个接口自带的page属性,先在网络数据获取的接口的url携带参数data里写一个传参的变量 page: this.currentPage,用来给url携带页码参数

然后在页面的data里定义这个变量currentPage,使他的初始默认值是1,就是一刷新页面进来,默认取第一页的值,然后在上拉刷新onReachBottom这个页面生命周期方法中,将默认值为1的这个当前页码的值++

data() {
  return {
        navIndex:0,
        navArr: [],
        newsArr:[],
        currentPage:1
  }
},
                
onLoad() {
      this.getNavData()
      this.getNewsData()
		},
    onReachBottom(){
      this.currentPage++;
    },
methods: {

然后再在触底加载更多这个页面声明周期中获取一次新闻列表的数据,就把新的数据获取到了,这样写的效果是当前页码是几,他就获取第几页的数据展示到页面,有一个问题,走到最后一页数据不够一页时,就没法触底加载更多了,也回不去了

所以一般在移动端都是将获取到的新数据和之前的数据拼接起来

具体写法是在获取网络数据的方法里,写一个数组,将之前的页码拿到的值和之后的页码拿到的值写到一个数组里,但是这样就成了一个二维数组了,使用es6的解构赋值,就是前面加三个点,将两个数组展开变成一个数组

// 获取新闻列表数据
      getNewsData(id=50){
        uni.request({
          url:"https://ku.qingnian8.com/dataApi/news/newslist.php",
          data:{
            cid:id,
            page: this.currentPage
          },
          success:res=>{
            // this.newsArr = res.data
            this.newsArr = [...this.newsArr, ...res.data]
          }
        })
      }

index.vue页面全部代码

<template>
	<view class="home">
    
      <scroll-view scroll-x class="navScroll">
        <view class="item" 
        :class="index==navIndex?'active':''" 
        v-for="(item, index) in navArr" 
        @click="clickNav(index, item.id)"
        :key="item.id">
          {{item.classname}}
        </view>
      </scroll-view>

    <view class="content">
      <view class="row" v-for="item in newsArr" :key = "item.id">
        <newsStyle :item="item" @click.native="goDetail"></newsStyle>
      </view>
    </view>
    
    <view class="nodata" v-if="!newsArr.length">
      <image src="../../static/images/nodata.png" mode="widthFix"></image>
    </view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
        navIndex:0,
        navArr: [],
        newsArr:[],
        currentPage:1
			}
		},
		onLoad() {
      this.getNavData()
      this.getNewsData()
		},
    onReachBottom(){
      this.currentPage++;
      this.getNewsData()
    },
		methods: {
      // 点击导航栏切换选中项
      clickNav(index,id){
        this.navIndex = index;
        this.getNewsData(id)
      },
      // 跳转到详情页
      goDetail(){
        uni.navigateTo({
          url:"/pages/detail/detail"
        })
      },
      // 获取导航列表数据--导航栏内容要在一刷新页面就出现
      // 所以在onload中调用这个方法
      getNavData(){
        uni.request({
          url:"https://ku.qingnian8.com/dataApi/news/navlist.php",
          success: res=>{
            this.navArr = res.data
          }
        })
      },
      // 获取新闻列表数据
      getNewsData(id=50){
        uni.request({
          url:"https://ku.qingnian8.com/dataApi/news/newslist.php",
          data:{
            cid:id,
            page: this.currentPage
          },
          success:res=>{
            // 将获取到的当前页面数据赋值给newsArr
            // this.newsArr = res.data
            // 将当前页面的数据和之前获取的数据拼接起来并赋值给newsArr
            this.newsArr = [...this.newsArr, ...res.data]
          }
        })
      }
		}
	}
</script>

<!-- scoped:说明这是局部样式 -->
<style lang="scss" scoped>
  .navScroll {
    height: 100rpx;
    background: #f7f8fa;
    // 这一句是使元素不换行,一旦换行了就显示不全
    // 又因为有行高,他没法两行显示,有一些就被隐藏了
    // 加了这一行才能让多出来的小盒子能滑动显示
    white-space: nowrap;
    position: fixed;
    top: var(--window-top);
    left: 0;
    z-index: 10;
    // 去除导航栏横向滚动条
    	// /deep/ ::-webkit-scrollbar {
    	// 		width: 4px !important;
    	// 		height: 1px !important;
     //      overflow: auto !important;
    	// 		background: transparent !important;
     //      -webkit-appearance: auto !important;
    	// 		display: block;
    	// 	}
      // 去除滚动条
      		::-webkit-scrollbar {
      			display: none;
      			width: 0 !important;
      			height: 0 !important;
      			-webkit-appearance: none;
      			background: transparent;
      			color: transparent;
      		}

    .item {
      font-size: 40rpx;
      // 使导航栏的每一个小盒子在一行显示
      display: inline-block;
      // 加行高
      line-height: 100rpx;
      // 给每个小盒子加一个padding,上下0 左右30rpx
      padding: 0 30rpx;
      color: #333;
      &.active {
        color: #31c27c;
      }
    }
  }
  
  .content {
    padding: 30rpx;
    padding-top: 95rpx;
    .row {
      border-bottom: 1px solid #efefef;
      padding: 20rpx 0;
    }
  }
  .nodata {
    // 使图片居中显示
    display: flex;
    justify-content: center;
    image{
      width: 360rpx;
    }
  }
</style>

这样写就第一栏能行,再点击第二栏就出bu了,因为当前页码currentpage一直在++,所以,第一栏如果点到第三页,再点击第二栏国际新闻时,国际新闻是从第三页开始加载的数据,而不是从第一页开始

解决办法是:

在点击切换导航栏的方法中,店家切换导航栏之后,获取新数据之前,将页码切换到第一页,这样,每次点击切换导航栏,都是从第一页开始点的

还要把前一栏获取到的数据清空,要不然他会把所有页面的数据全部拼接在一起,还有一个问题是他不会自动回到顶部

methods: {
      // 点击导航栏切换选中项
      clickNav(index,id){
        this.navIndex = index;
        // 切换导航栏时,将点击的页码置为1,否则不同栏目的页码将会一直++
        this.currentPage = 1;
        // 重置已经获取到的数据,不清空会把不同栏目的数据拼接在一起
        this.newsArr = [];
        this.getNewsData(id)
},

现在全部的index.vue代码

<template>
	<view class="home">
    
      <scroll-view scroll-x class="navScroll">
        <view class="item" 
        :class="index==navIndex?'active':''" 
        v-for="(item, index) in navArr" 
        @click="clickNav(index, item.id)"
        :key="item.id">
          {{item.classname}}
        </view>
      </scroll-view>

    <view class="content">
      <view class="row" v-for="item in newsArr" :key = "item.id">
        <newsStyle :item="item" @click.native="goDetail"></newsStyle>
      </view>
    </view>
    
    <view class="nodata" v-if="!newsArr.length">
      <image src="../../static/images/nodata.png" mode="widthFix"></image>
    </view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
        navIndex:0,
        navArr: [],
        newsArr:[],
        currentPage:1
			}
		},
		onLoad() {
      this.getNavData()
      this.getNewsData()
		},
    onReachBottom(){
      this.currentPage++;
      this.getNewsData()
    },
		methods: {
      // 点击导航栏切换选中项
      clickNav(index,id){
        this.navIndex = index;
        // 切换导航栏时,将点击的页码置为1,否则不同栏目的页码将会一直++
        this.currentPage = 1;
        // 重置已经获取到的数据,不清空会把不同栏目的数据拼接在一起
        this.newsArr = [];
        this.getNewsData(id)
      },
      // 跳转到详情页
      goDetail(){
        uni.navigateTo({
          url:"/pages/detail/detail"
        })
      },
      // 获取导航列表数据--导航栏内容要在一刷新页面就出现
      // 所以在onload中调用这个方法
      getNavData(){
        uni.request({
          url:"https://ku.qingnian8.com/dataApi/news/navlist.php",
          success: res=>{
            this.navArr = res.data
          }
        })
      },
      // 获取新闻列表数据
      getNewsData(id=50){
        uni.request({
          url:"https://ku.qingnian8.com/dataApi/news/newslist.php",
          data:{
            cid:id,
            page: this.currentPage
          },
          success:res=>{
            // 将获取到的当前页面数据赋值给newsArr
            // this.newsArr = res.data
            // 将当前页面的数据和之前获取的数据拼接起来并赋值给newsArr
            this.newsArr = [...this.newsArr, ...res.data]
          }
        })
      }
		}
	}
</script>