vue uniapp微信小程序 使用scroll-view 的@scrolltolower触底事件操作加载每页数据

332 阅读1分钟

image.png

<template>
  <view class="u-wrap">
    <view class="u-search-box">
      <view class="u-search-inner">
        <u-input v-model="formItem.name" class="u-search-text">请输入搜索内容</u-input>
        <view class="u-search-icon" @click="searchFn">
          <u-icon name="search" color="#fff" :size="28"></u-icon>
        </view>
      </view>
    </view>
    <view class="u-menu-wrap">
      <scroll-view scroll-y scroll-with-animation class="u-tab-view menu-scroll-view" :scroll-top="scrollTop">
        <view v-for="(item, index) in tabbar" :key="index" class="u-tab-item"
          :class="[current == index ? 'u-tab-item-active' : '']" :data-current="index"
          @tap.stop="swichMenu(index,item)">
          <text class="u-line-1">{{ item.name }}</text>
        </view>
      </scroll-view>
      <block v-for="(item, index) in tabbar" :key="index">
        <scroll-view scroll-y class="right-box" v-if="current == index" @scrolltolower="scrolltolowerFn">
          <view class="page-view">
            <view class="class-item">
              <view class="item-container" v-for="(lists,i) in menuItem" :key="i">
                <!-- v-if="item.id == lists.class_id" -->
                <view class="thumb-box">
                  <view class="item-menu-image">
                    <image :src="lists.img" mode=""></image>
                  </view>
                  <view class="item-menu-right">
                    <view class="book_name">{{lists.name}}</view>
                    <view>编号:{{lists.number}}</view>
                    <view class="book_title">
                      <view>书架:{{lists.shelf}}</view>
                      <text class="borrow" v-if="is_borrow==1" @click="toBorrowFn(lists)">借阅</text>
                    </view>
                    <view class="quantity">
                      <text style="font-size: 28rpx;color: #EB7F36;">{{lists.price}} 元</text>
                      <text>总数 {{lists.total_num}}</text>
                      <text>已借 {{lists.borrow_num}}</text>
                      <text>库存 {{lists.stock_num}}</text>
                    </view>
                    <view style="width: 430px;height: 4rpx;background: #F1F1F1;margin-top: 30rpx;"></view>
                  </view>
                </view>
              </view>
            </view>
          </view>
        </scroll-view>
      </block>
    </view>
  </view>
</template>

<script> 
import { book_class_lists,book_lists } from "../../api/service.js";
export default {
  data () {
    return {
      tabbar: [],
      formItem: {
        name: '',
        page: 1,
        class_id: '',
        page_size:20
      },
      is_reach: true,//是否可 下拉
      menuItem: [],
      newMenuItem: [],
      is_borrow: "",
      scrollTop: 0, //tab标题的滚动条位置
      current: 0, // 预设当前项的值
      menuHeight: 0, // 左边菜单的高度
      menuItemHeight: 0, // 左边菜单item的高度
    };
  }, 
  onShow () {
    this.getClassLists()
    this.getBookLists()
  },
  methods: {
  //触底事件
    scrolltolowerFn () {
      if(this.is_reach) {
        this.formItem.page++;
        this.getBookLists(); 
      }
    },
    async getClassLists () {
      const res=await book_class_lists()
      this.tabbar=[{ name: '全部' },...res.lists.data]
    },
    //右侧内容
    async getBookLists () {
      uni.showLoading({
        title: '加载中'
      });
      const res=await book_lists(this.formItem)
      if(res) {
        this.is_borrow=res.is_borrow
        this.menuItem=this.menuItem.concat(res.lists.data);
        if(res.lists.current_page<res.lists.last_page) {
          this.is_reach=true
        } else {
          this.is_reach=false

        }
        uni.hideLoading();
      }
    },
    searchFn () {
      this.getBookLists()
    },
    toBorrowFn (item) {
      this.needTokenLink(`/pagesA/bookManage/bookApplyDetail?id=${item.id}`)
    },
    getImg () {
      return Math.floor(Math.random()*35);
    },
    // 点击左边的栏目切换
    async swichMenu (index,item) {
      if(index==this.current) return;
      this.current=index;
      this.menuItem=[]
      //判断如果是全部的话就展示所有的数据 class_id清空即可展示全部数据
      if(this.current==0) {
        this.formItem.class_id=''
      } else {
        this.formItem.class_id=item.id
        this.formItem.page=1
      }
      this.getBookLists()
      // 如果为0,意味着尚未初始化
      if(this.menuHeight==0||this.menuItemHeight==0) {
        await this.getElRect("menu-scroll-view","menuHeight");
        await this.getElRect("u-tab-item","menuItemHeight");
      }
      // 将菜单菜单活动item垂直居中
      this.scrollTop=index*this.menuItemHeight+this.menuItemHeight/2-this.menuHeight/2;
    },
    // 获取一个目标元素的高度
    getElRect (elClass,dataVal) {
      new Promise((resolve,reject) => {
        const query=uni.createSelectorQuery().in(this);
        query
          .select("."+elClass)
          .fields({ size: true },(res) => {
            // 如果节点尚未生成,res值为null,循环调用执行
            if(!res) {
              setTimeout(() => {
                this.getElRect(elClass);
              },10);
              return;
            }
            this[dataVal]=res.height;
          })
          .exec();
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.u-wrap { 
  height: calc(101vh);
  /* #ifdef H5 */
  height: calc(100vh-var(--window-top));
  /* #endif */
  display: flex;
  flex-direction: column;
}
.u-search-box {
  padding: 18rpx 30rpx;
  background: #fff;
}
.u-menu-wrap {
  flex: 1;
  display: flex;
  overflow: hidden;
}
.u-search-inner {
  background: #f5f5f5;
  border-radius: 100rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0rpx 16rpx;
}
.u-search-text {
  width: 550rpx;
  font-size: 26rpx;
  height: 78rpx;
  color: $u-tips-color;
  margin-left: 10rpx;
}
.u-search-icon {
  width: 50rpx;
  height: 50rpx;
  line-height: 50rpx;
  text-align: center;
  background: #eb7f36;
  border-radius: 50%;
  margin-right: 10rpx;
}
.u-tab-view {
  width: 180rpx;
  height: 100%;
}
.u-tab-item {
  height: 120rpx;
  background: #f6f6f6;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 30rpx;
  color: #444;
  font-weight: 400;
  line-height: 1;
}
.u-tab-item-active {
  position: relative;
  color: #eb7f36;
  font-size: 30rpx;
  background: #fff;
}
.u-tab-view {
  height: 100%;
}
.right-box {
  background-color: rgb(250, 250, 250);
}
.page-view {
  padding: 16rpx;
}
.class-item {
  margin-bottom: 30rpx;
  background-color: #fff;
  padding: 16rpx;
  border-radius: 8rpx;
}
.item-title {
  font-size: 26rpx;
  color: $u-main-color;
  font-weight: bold;
}
.item-menu-name {
  font-weight: normal;
  font-size: 24rpx;
  color: $u-main-color;
}
.item-container {
  display: flex;
  flex-wrap: wrap;
}
.thumb-box {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 20rpx;
  .item-menu-image {
    width: 100rpx;
    height: 148rpx;
    margin-right: 20rpx;
    margin-bottom: 20rpx;
    background: #999;
    image {
      width: 100%;
      height: 100%;
    }
  }
  .item-menu-right {
    width: 420rpx;
    font-size: 20rpx;
    color: #999;
    .book_name {
      font-size: 24rpx;
      color: #000;
      margin-bottom: 10rpx;
      overflow: hidden;
      -webkit-line-clamp: 2;
      display: -webkit-box;
      -webkit-box-orient: vertical;
      text-overflow: ellipsis;
    }
    .book_title {
      display: flex;
      justify-content: space-between;
      align-items: center;

      .borrow {
        width: 100rpx;
        height: 48rpx;
        line-height: 48rpx;
        font-size: 26rpx;
        text-align: center;
        background: #eb7f36;
        color: #fff;
        border-radius: 24rpx;
      }
    }
    .quantity {
      width: 350rpx;
      display: flex;
      justify-content: space-around;
      align-items: center;
      margin-top: 10rpx;
      margin-left: -12rpx;
    }
  }
}
</style>