vue 来写移动端,实现上拉加载,下拉刷新数据

本项目是用vue +elementui来写移动端 的:

首先创建一个每个需要上拉加载数据的模板组件 LoadMore.vue

<template>
  <div id="LoadMore" class="clearfix">
    <div class="load-more-wrapper clearfix">
      <div class="load-refresh refresh" v-show="isRefresh">
        {{refreshText}}
        <i class="el-icon-bottom"></i>
      </div>
      <div
        class="inner"
        @touchstart="touchStart($event)"
        @touchend="touchEnd($event)"
      >
        <slot></slot>
        <div class="load-more" v-show="enableLoadMore">
          {{loadMoreText}}
          <i class="el-icon-top"></i>
        </div>
        <div class="load-end" v-show="!enableLoadMore">已经到底了!</div>
      </div>
    </div>
  </div>
</template>

<script>

export default {
  name: "LoadMore",
  props: {
    enableLoadMore: {
      type: Boolean,
      default: true
    },
    onLoadMore: {
      type: Function,
      default: undefined,
      require: false
    }  
  },
  data() {
    return {
      isRefresh: false,
      refreshText: "下拉刷新",
      loadMoreText: "上拉加载更多",
      startX: 0,
      startY: 0,
      isLoading: false,
      top: 0,
      touching: false,
      scrollTop: 0,
      loading:""
    };
  },
  methods: { 
    openFullScreen() {//设置弹出框
        this.loading = this.$loading({
          lock: true,
          text: 'Loading',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)'
        });    
      },
    onEnlargeText: function(enlargeAmount) {},
    touchStart(e) {
      this.startY = e.targetTouches[0].pageY;
      this.startX = e.targetTouches[0].pageX;
    },
    closeloading(){
      this.loading.close();
    },
    scrollToEnd(e) {
      let windowHeight = window.screen.height;
      let scrollHeight = this.$el.scrollHeight;
      let clientHeight = this.$el.clientHeight;
      this.scrollTop =
      document.documentElement.scrollTop || document.body.scrollTop;
      if (this.scrollTop == 0 && this.touching) {   
        this.isRefresh = false;
        this.doLoadMore("total");// 下拉刷新
      }
      if (this.touching) {
        // 下拉动作不加载下一页
        return false;
      }
      if (!this.enableLoadMore) {
        this.$message({
          showClose: true,
          message: "没有更多数据了!",
          type: "error",
          center: true
        });
      } else if (
        scrollHeight > windowHeight &&
        this.scrollTop + windowHeight >= scrollHeight &&
        this.scrollTop + clientHeight >= scrollHeight
      ) {
        this.doLoadMore();
        this.loading
      } else if (
        scrollHeight < windowHeight &&
        this.scrollTop + clientHeight >= scrollHeight
      ) {
        this.doLoadMore();
      }
      
    },
    touchEnd(e) {
      if (this.isLoading) {
        return;
      }
      let endX = e.changedTouches[0].pageX,
        endY = e.changedTouches[0].pageY,
        dy = this.startY - endY,
        dx = endX - this.startX;
      if (Math.abs(dx) < 2 && Math.abs(dy) < 2) {
        return;
      }
      if (endY < this.startY) {
        this.touching = false; // 上滑
        this.scrollToEnd(e);
      } else if (endY > this.startY) {
        this.touching = true; // 下拉
        this.scrollToEnd(e);
      }
      this.isRefresh = true;
    },
    doLoadMore(total = "") {
      this.isLoading = true;
      this.loadMoreText = "加载中...";
      this.openFullScreen();//显示遮罩层
      this.onLoadMore(this.loadDone, total);
    },
    loadDone() {
      this.isLoading = false;
      this.loadMoreText = "上拉加载更多";
    } 
  } 
};
</script>
 
<style lang="less" scoped>
#LoadMore{
.load-more-wrapper {
  height: 100%;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  transition-duration: 300ms;
  .inner {
    width: 100%;
    height: 100%;
    .load-refresh,
    .load-more,
    .load-end {
      color: #aea699;
      font-size: 1rem;
      margin: 0.3rem 0;
      text-align: center;
    }
  }
  .refresh {
    position: absolute;
    top: 44px;
    left: 44%;
    z-index: 9;
    color: #aea699;
    font-size:.75rem;
    text-align: center;
  }
}
}
</style>

然后在父页面引入子组件LoadMore.vue

  <template>
  <div id="classSchedule" class="clearfix">
    <div class="main clearfix">
     
      <div class="main-page-wrapper clearfix">
        <LoadMore :onLoadMore="onLoadMore" :enableLoadMore="enableLoadMore" ref="LoadMore">
          <!-- 表格 -->
          <div class="contents">
            <el-row type="flex" class="row-bg header_fidx" :span="24">
              <el-col :span="8" class="col_row1">
                <a class="grid-content rows">班级名称</a>
              </el-col>
              <el-col :span="8" class="col_row1">
                <a class="grid-content">所在年级</a>
              </el-col>
              <el-col :span="8" class="col_row2">
                <a class="grid-content">详情</a>
              </el-col>
            </el-row>
            <el-row
              type="flex"
              class="row-bg"
              :span="24"
              v-for="(item,index) in tableData"
              :key="index"
            >
              <el-col :span="8" class="col_row1">
                <a class="grid-content rows">{{item.className}}</a>
              </el-col>
              <el-col :span="8" class="col_row1">
                <a class="grid-content">{{item.gradeName}}</a>
              </el-col>
              <el-col :span="8" class="col_row2">
                <div @click="getmsg(item) ">
                  <i class="el-icon-arrow-right grid-content"></i>
                </div>
              </el-col>
            </el-row>
          </div>
        </LoadMore>
      </div>
    </div>
  </div>
</template>
 
 <script>
import LoadMore from "@/components/LoadMore.vue";

export default {
  name: "classSchedule",
  components: {
    LoadMore
  },
  data() {
    return {
      tableData: [],
      page: 1,
      enableLoadMore: true,
      isRefresh: false,
      lastPage: ""
    };
  },
  created() {
    this.Schedulle();
  },
  methods: {
   //初始页面数据渲染
    async Schedulle() {
      let res = await this.$api.CLASS_SCHEDULE("");
      if (res.data.errcode == 0) {
        this.tableData = res.data.items;
        this.lastPage = res.data.lastPage;
      } else {
        this.$message({
          showClose: true,
          message: "错了哦,获取数据失败!",
          type: "error",
          center: true
        });
        console.log(error);
      }
    },

     //下拉加载数据
    onLoadMore(done, total = "") {
      setTimeout(() => {
        if (!this.enableLoadMore) {
          return;
        }
        if (total == "") {
          this.page = this.page + 1;
        }
        this.getListData(total);
        done();
      }, 200);
    },
    getListData(total = "") {
      if (this.page <= this.lastPage) {
        this.$api
          .CLASS_SCHEDULE("page=" + this.page + "&total=" + total+"&gradeId=" + this.chindId + "")
          .then(res => {
            this.$refs.LoadMore.closeloading(); // 取消遮罩层
            if (res.data.errcode != 0) {
              this.$message({
                showClose: true,
                message: "没有更多数据了!",
                type: "error",
                center: true
              });
              // this.enableLoadMore = false;
              return false;
            }
            if (total == "") {
              this.tableData = this.tableData.concat(res.data.items);
            } else {
              this.tableData = res.data.items;
            }
          });
      } else {
        this.$message({
          showClose: true,
          message: "没有更多数据了!",
          type: "error",
          center: true
        });
        this.$refs.LoadMore.closeloading(); // 取消遮罩层
      }
    }
  }
};
</script>
 <style  lang="less">
  @import "../../assets/CSS/less/form.less";
</style>

如有相似页面的话,也可把需要你上拉加载数据的部分分成一个组件引入

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值