better-scoll实现上拉加载更多数据

实现的需求

  1. 使用better-scroll下拉刷新
  2. 用mixin将列表请求进行封装

scroll.vue

<template>
  <div ref="wrapper">
    <div>
      <slot></slot>
      <!-- 加载显示,可以替换别的 -->
      <div class="scrollBottom" v-if="pullup">{{ showText[scrollText] }}</div>
    </div>
  </div>
</template>

<script>
import BScroll from "better-scroll";
import _ from "lodash";
export default {
  name: "dxScroll",
  data() {
    return {
      scrollY: 0,
      showText: ["上拉加载更多", "正在加载...", "暂无数据"]
    };
  },
  props: {
    probeType: {
      type: Number,
      default: 1
    },
    click: {
      type: Boolean,
      default: true
    },
    data: {
      type: Array,
      default: null
    },
    listenScroll: {
      type: Boolean,
      default: false
    },
    //是否开启加载
    pullup: {
      type: Boolean,
      default: false
    },
    refreshDelay: {
      type: Number,
      default: 20
    },
    scrollText: {
      type: Number,
      default: 0
    }
  },
  mounted() {
    setTimeout(() => {
      this._initScroll();
      this.refresh();
    });
  },
  methods: {
    _initScroll() {
      if (!this.$refs.wrapper) {
        return;
      }
      this.scroll = new BScroll(this.$refs.wrapper, {
        probeType: this.probeType,
        click: this.click
      });

      if (this.listenScroll) {
        let _this = this;
        this.scroll.on("scroll", pos => {
          _this.$emit("scroll", pos);
        });
      }
      if (this.pullup) {
        this.scroll.on("scrollEnd", () => {
          if (this.scroll.y <= this.scroll.maxScrollY + 50) {
            //发生上拉事件触发
            //实现上移显示
            //这个是为了防止连续滑动导致列表加载错误,防止如果只有一条数据会自动执行改函数
              if (this.scroll.maxScrollY == this.scrollY || this.scroll.maxScrollY == 0) {
                return;
              }
              this.scrollY = this.scroll.maxScrollY;
              this.$emit("scrollToEnd");
          }
        });
      }
    },
    enable() {
      this.scroll && this.scroll.enable();
    },
    disable() {
      this.scroll && this.scroll.disable();
    },
    refresh() {
      setTimeout(() => {
        this.scroll && this.scroll.refresh();
      }, 100);
    },
    scrollTo() {
      this.scroll && this.scroll.scrollTo.apply(this.scroll, arguments);
    },
    scrollToElement() {
      this.scroll && this.scroll.scrollToElement.apply(this.scroll, arguments);
    }
  },
  watch: {
    data() {
      setTimeout(() => {
        this.refresh();
      }, this.refreshDelay);
    }
  }
};
</script>

<style lang="scss" scoped>
.scrollBottom {
  color: #969799;
  line-height: 50px;
  height: 50px;
  text-align: center;
}
</style>



mixin.js


import $http from "@u/http";
export default {
  data() {
    return {
      form: {},
      tableData: [], //表格数据
      page: {
        //分页数据
        pageSize: 10,
        pageNum: 1
      },
      pullup: true,
      scrollText: 0 //加载状态,
    };
  },
  methods: {
    //获取数据

    async getList(callback) {
      if (!this.getTableURL) return; //需配置请求地址
      let that = this;
      this.scrollText = 1;
      await $http
        .get(that.getTableURL, {
          ...this.form,
          pageNo: that.page.pageNum
        })
        .then(res => {
          //    console.log(res)
          let lastPage =    parseInt(res.data.data.totalRecord / that.page.pageSize) + 1;
          if (res.data.code == "0000") {
            if (
              lastPage >= that.page.pageNum
            ) {
              if(lastPage == that.page.pageNum){
                that.scrollText = 2;
              }else{
                that.scrollText =  0
              }
              callback(res.data.data.list);
            } else {
              that.scrollText = 2;
            }
          } else {
            // callback(res.msg);
            that.scrollText = 2;
          }
        });
    }
  }
};

list.vue

 <dxScroll
          class="km-body"
          :pullup="true" 
          ref="scroll"
          @scrollToEnd="pullRefresh"
        >
          <div class="doctor-content">
            <div v-for="(v, i) in doctorList" :key="i" class="doctor-items">
              <div class="doctor-item">
                <div class="doctor-img">
                  <img :src="v.img" alt="" />
                </div>
                <div class="doctor-info">
                  <div class="doctor-top">
                    <div class="doctor-name">
                      {{ v.name }}
                    </div>
                    <div class="font-middle-nomal">
                      主任医生
                    </div>
                    <div class="doctor-hospital" v-if="v.hosLevel">三甲</div>
                  </div>
                  <div class="doctor-ky">
                    <div class="font-middle-nomal">
                      {{ v.porject }}
                    </div>
                    <div class="font-middle-nomal">
                      {{ v.doctor_hospital }}
                    </div>
                  </div>
                  <div class="doctor-decrease">
                    擅长:{{ v.hobby.join(",") }}
                  </div>
                  <div class="doctor-pingjia">
                    <div class="doctor-star">
                      <afIcon class="iconfont icon-star2" size="sIcon" />
                      <span>{{ v.star }}</span>
                      <div>月回答 {{ v.monthAnswer }}</div>
                      <div>月处方 {{ v.monthChufang }}</div>
                      <div>{{ v.AnswerTime }}分钟相应</div>
                    </div>
                  </div>
                  <div class="doctor-tab">
                    <div v-for="(tags, k) in v.tags" :key="k">
                      {{ tags }}
                    </div>
                  </div>
                  <div class="doctor-coupon" v-if="v.coupon">
                    <div><dx-coupon></dx-coupon></div>
                  </div>
                  <div class="doctor-price">
                    <div>图文 ¥{{ v.picPrice }}</div>
                    <div>电话 ¥{{ v.callPrice }}</div>
                    <span>问医生</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </dxScroll>
 methods: {
 	getDoctorList() {
      this.getList(res => {
        for (let i of res) {
          this.doctorList.push(i);
        }
        this.$refs.scroll.refresh();
      });
    },
 }

效果演示

正常状态
加载过程
暂无数据
美中不足

  1. 在防止多次上滑的代码其实可以优化
  2. 存在一定的耦合

后台数据接口mock : https://www.fastmock.site/mock/006c006287b8911f6b7585e6ee959cda/dx/getDoctorList

better-scroll官网案例: https://better-scroll.github.io/docs/zh-CN/guide/base-scroll-options.html#disabletouch
better-scroll上拉刷新插件: https://better-scroll.github.io/docs/zh-CN/plugins/pullup.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值