基于mescroll.js封装移动端下拉刷新上拉加载更多组件

一、内容参考官网

​​​​​​mescroll -- 精致的下拉刷新和上拉加载js框架
多看看官方文档就知道了。

二、代码
​
<template>
  <div>
    <!--mescroll滚动区域的基本结构-->
    <mescroll-vue
      ref="mescroll"
      :down="mescrollDown"
      :up="mescrollUp"
      @init="mescrollInit"
    >
      <div :id="parentId">
        <!--内容...-->
        <slot :dataList="dataList"></slot>
      </div>
    </mescroll-vue>
  </div>
</template>

<script lang="ts">
// 引入mescroll的vue组件
import MescrollVue from 'mescroll.js/mescroll.vue'
// import topIcon from "@/assets/toTop.png";
// import { showFailToast } from "vant";

export default {
  components: {
    MescrollVue // 注册mescroll组件
  },
  data() {
    const parentId = Number(
      Math.random().toString().substr(3, 36) + Date.now()
    ).toString(36)
    return {
      mescroll: null, // mescroll实例对象
      parentId: parentId,
      mescrollDown: {
        auto: false,
        callback: this.downCallback
      }, //下拉刷新的配置. (如果下拉刷新和上拉加载处理的逻辑是一样的,则mescrollDown可不用写了)
      mescrollUp: {
        // 上拉加载的配置.
        callback: this.upCallback, // 上拉回调,此处简写; 相当于 callback: function(page, mescroll) { }
        //以下是一些常用的配置,当然不写也可以的.
        page: {
          num: 0, //当前页 默认0,回调之前会加1; 即callback(page)会从1开始
          size: 10 //每页数据条数,默认10
        },
        htmlNodata: '<p class="upwarp-nodata">-- 数据已全部加载 --</p>',
        noMoreSize: 1, //如果列表已无数据,可设置列表的总数量要大于5才显示无更多数据;
        // 避免列表数据过少(比如只有一条数据), 显示无更多数据会不好看
        // 这就是为什么无更多数据有时候不显示的原因
        // toTop: {
        //   //回到顶部按钮
        //   src: topIcon, //图片路径,默认null,支持网络图
        //   offset: 1000 //列表滚动1000px才显示回到顶部按钮
        // },
        empty: {
          //列表第一页无任何数据时,显示的空提示布局; 需配置warpId才显示
          warpId: parentId, //父布局的id (1.3.5版本支持传入dom元素)
          // icon: "./static/mescroll/mescroll-empty.png", //图标,默认null,支持网络图
          // use: true,
          // icon: '/static/nodata.png',
          tip: '暂无数据'
        }
      },
      dataList: [] // 列表数据
    }
  },
  props: ['config'],

  // beforeRouteEnter(to, from, next) {
  //   // 如果没有配置顶部按钮或isBounce,则beforeRouteEnter不用写
  //   next(vm => {
  //     // 滚动到原来的列表位置,恢复顶部按钮和isBounce的配置
  //     vm.$refs.mescroll && vm.$refs.mescroll.beforeRouteEnter();
  //   });
  // },
  // beforeRouteLeave(to, from, next) {
  //   // 如果没有配置顶部按钮或isBounce,则beforeRouteLeave不用写
  //   // 记录列表滚动的位置,隐藏顶部按钮和isBounce的配置
  //   this.$refs.mescroll && this.$refs.mescroll.beforeRouteLeave();
  //   next();
  // },
  mounted() {
    const { warpId, useDown } = this.$props.config
    if (useDown + '' == 'false') {
      this.mescrollDown.use = useDown
    }
    this.mescrollUp.empty.warpId = warpId || this.parentId
  },
  methods: {
    // mescroll组件初始化的回调,可获取到mescroll对象
    mescrollInit(mescroll: any) {
      this.mescroll = mescroll // 如果this.mescroll对象没有使用到,则mescrollInit可以不用配置
    },
    downCallback() {
      if (this.mescroll.optUp.use) {
        this.mescroll.resetUpScroll()
      } else {
        setTimeout(() => {
          this.mescroll.endSuccess()
        }, 500)
      }
    },
    // 上拉回调 page = {num:1, size:10}; num:当前页 ,默认从1开始; size:每页数据条数,默认10
    upCallback(page: any, mescroll: any) {
      const {
        config: { request, params }
      } = this
      // if (typeof request !== 'function') {
      //   console.error('Request is not a function:', request)
      //   // 适当处理错误,可以抛出异常或提前返回
      //   debugger
      // }
      debugger
      request(
        Object.assign(
          {},
          {
            page: page.num,
            rows: page.size
          },
          params
        )
      )
        .then((result: any) => {
          debugger
          // 请求的列表数据
          let arr
          //  后端服务返回数据格式没有统一  部分返回状态码  部分直接返回数据
          //这个格式根据
          if (result.data) {
            arr =
              result.data.rows ||
              result.data.commonScheduleDataList ||
              result.data.opinionList ||
              result.data
          } else {
            arr = result.rows
          }
          // 如果是第一页需手动置空列表
          if (page.num === 1) this.dataList = []
          // 把请求到的数据添加到列表
          this.dataList = this.dataList.concat(arr)
          // 数据渲染成功后,隐藏下拉刷新的状态
          this.$nextTick(() => {
            mescroll.endSuccess(arr.length)
          })
        })
        .catch((e: any) => {
          console.error(e)
          debugger
          // 联网失败的回调,隐藏下拉刷新和上拉加载的状态;
          mescroll.endErr()
        })
      /*const { config: { url, method, params } } = this;
      const headers = {
        'Content-Type': 'application/json; charset=utf-8'
      }
      let newParams = Object.assign({}, {
        page: page.num,
        rows: page.size
      }, params)

      // 联网请求
      axios({
        method,
        url,
        params: newParams,
        headers
      }).then((response) => {
        const { data: { code } } = response;
        if (code == 551) {
          showFailToast('登录状态已过期,请重新登录');
          if (process.env.NODE_ENV === "development") {
            window.location.hash = '#/login';
          } else {
            window.Android.startLoginActivity();
          }
        } else {
          // 请求的列表数据
          let arr = response.data.data.rows || response.data.data.commonScheduleDataList;
          // 如果是第一页需手动置空列表
          if (page.num === 1) this.dataList = []
          // 把请求到的数据添加到列表
          this.dataList = this.dataList.concat(arr);
          // 数据渲染成功后,隐藏下拉刷新的状态
          this.$nextTick(() => {
            mescroll.endSuccess(arr.length)
          })
        }
      }).catch((e) => {
        // 联网失败的回调,隐藏下拉刷新和上拉加载的状态;
        mescroll.endErr()
      })*/
    }
  }
}
</script>

<style lang="scss">
/*通过fixed固定mescroll的高度*/

.mescroll {
  position: fixed;
  top: vh(130);
  bottom: 0;
  height: auto;
}

.mescroll-totop {
  bottom: vh(55);
}
</style>

​
<template>
  <div class="main">
    <div class="home-box">
      <meSroll ref="meScrollRef" :config="config">
        <template #default="{ dataList }">
          <div class="list">
            {{ dataList }}
          </div>
        </template>
      </meSroll>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import meSroll from '@/components/meSroll/index.vue'

//定义死数据
const testList = ref({
  page: 1,
  // rows: 10,
  total: 12,
  rows: [
    {
      id: 0,
      address: '南昌',
      phone: '173547236535'
    },
    {
      id: 1,
      address: '南昌',
      phone: '173547236535'
    },
    {
      id: 2,
      address: '南昌',
      phone: '173547236535'
    },
    {
      id: 3,
      address: '南昌',
      phone: '173547236535'
    },
    {
      id: 4,
      address: '南昌',
      phone: '173547236535'
    },
    {
      id: 5,
      address: '南昌',
      phone: '173547236535'
    },
    {
      id: 6,
      address: '南昌',
      phone: '173547236535'
    },
    {
      id: 7,
      address: '南昌',
      phone: '173547236535'
    },
    {
      id: 8,
      address: '南昌',
      phone: '173547236535'
    },
    {
      id: 9,
      address: '南昌',
      phone: '173547236535'
    },
    {
      id: 10,
      address: '南昌',
      phone: '173547236535'
    },
    {
      id: 11,
      address: '南昌',
      phone: '173547236535'
    }
  ]
})
//获取列表数据  后面换成接口就行
const getList = () => {
  return testList.value
}
// 查询组件配置
const config = ref({
  request: getList,//需要换成对应的获取列表数据接口
  params: {
    rows: 10
  }
})
const meScrollRef: any = ref('') //  下拉组件实例化

//主动触发下拉刷新
const handleQuery = () => {
  meScrollRef?.value?.mescroll.triggerDownScroll()
}
</script>
<style lang="scss" scoped>
.main {
  width: 100vw;
  height: 100vh;
  .home-box {
    height: 100%;
  }
}
</style>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值