简单封装vue移动端上拉加载更多

<template lang="html">

  <div class="load-moudle" @touchstart="touchStart($event)" @touchmove="touchMove($event)" @touchend="touchend($event)">

    <slot></slot>

    <footer class="load-more">

      <slot name="load-more">

        <div class="more-tip" v-if="pullUpState==1">

          <span class="more-text">{{pullUpInfo.moreText}}</span>

        </div>

        <div class="loading-tip" v-if="pullUpState==2">

          <span class="loading-icon"></span>

          <span class="loading-text">{{pullUpInfo.loadingText}}</span>

        </div>

        <div class="no-more-tip" v-if="pullUpState==3">

          <span class="connecting-line"></span>

          <span class="no-more-text">{{pullUpInfo.noMoreText}}</span>

          <span class="connecting-line"></span>

        </div>

      </slot>

    </footer>

  </div>

</template>

<script>

export default {

  props: {

    parentPullUpState: {

      default: 0

    },

    onInfiniteLoad: {

      type: Function,

      require: false

    }

  },

  data () {

    return {

      top: 0,

      pullUpState: 0, // 1:上拉加载更多, 2:加载中……, 3:我是有底线的

      isLoading: false, // 是否正在加载

      pullUpInfo: {

        moreText: '上拉加载更多',

        loadingText: '加载中...',

        noMoreText: '我是有底线的'

      },

      startX: 0,

      startY: 0,

      endX: 0,

      endY: 0

    }

  },

  created () {

    // console.log(this.pullUpState)

  },

  methods: {

    /**

     * 触摸开始,手指点击屏幕时

     * @param {object} e Touch 对象包含的属性

     */

    touchStart (e) {

      this.startX = e.touches[0].pageX

      this.startY = e.touches[0].pageY

    },

    /**

     * 接触点改变,滑动时

     * @param {object} e Touch 对象包含的属性

     */

    touchMove (e) {

      this.endX = e.changedTouches[0].pageX

      this.endY = e.changedTouches[0].pageY

      let direction = this.getSlideDirection(this.startX, this.startY, this.endX, this.endY)

      switch (direction) {

        case 0:

          // console.log('没滑动')

          break

        case 1:

          // console.log('向上')

          this.scrollToTheEnd()

          break

        case 2:

          // console.log('向下')

          break

        case 3:

          // console.log('向左')

          break

        case 4:

          // console.log('向右')

          break

        default:

      }

    },

    /**

     * 触摸结束,手指离开屏幕时

     * @param {object} e Touch 对象包含的属性

     */

    touchend (e) {

      this.isLoading = false

    },

    /**

     * 判断滚动条是否到底

     */

    scrollToTheEnd () {

      let innerHeight = document.querySelector('.load-moudle').clientHeight

      // 变量scrollTop是滚动条滚动时,距离顶部的距离

      let scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop

      // 变量scrollHeight是滚动条的总高度

      let scrollHeight = document.documentElement.clientHeight || document.body.scrollHeight

      // 滚动条到底部的条件

      if (scrollTop + scrollHeight >= innerHeight) {

        if (this.pullUpState !== 3 && !this.isLoading) {

          this.infiniteLoad()

        }

        // console.log('距顶部' + scrollTop + '滚动条总高度' + scrollHeight + '内容高度' + innerHeight)

      }

    },

    /**

     * 上拉加载数据

     */

    infiniteLoad () {

      if (this.pullUpState !== 0) {

        this.pullUpState = 2

        this.isLoading = true

        this.onInfiniteLoad(this.infiniteLoadDone)

      }

    },

    /**

     * 加载数据完成

     */

    infiniteLoadDone () {

      this.pullUpState = 1

    },

    /**

     * 返回角度

     */

    getSlideAngle (dx, dy) {

      return Math.atan2(dy, dx) * 180 / Math.PI

    },

    /**

     * 根据起点和终点返回方向 1:向上,2:向下,3:向左,4:向右,0:未滑动

     * @param {number} startX X轴开始位置

     * @param {number} startY X轴结束位置

     * @param {number} endX Y轴开始位置

     * @param {number} endY Y轴结束位置

     */

    getSlideDirection (startX, startY, endX, endY) {

      let dy = startY - endY

      let dx = endX - startX

      let result = 0

      // 如果滑动距离太短

      if (Math.abs(dx) < 2 && Math.abs(dy) < 2) {

        return result

      }

      let angle = this.getSlideAngle(dx, dy)

      if (angle >= -45 && angle < 45) {

        result = 4

      } else if (angle >= 45 && angle < 135) {

        result = 1

      } else if (angle >= -135 && angle < -45) {

        result = 2

      } else if ((angle >= 135 && angle <= 180) || (angle >= -180 && angle < -135)) {

        result = 3

      }

      return result

    }

  },

  watch: {

    parentPullUpState (curVal, oldVal) {

      this.pullUpState = curVal

    }

  }

}

</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->

<style scoped>

.load-more {

  width: 100%;

  color: #c0c0c0;

  background: #fafafa;

  font-size: 14px;

}

.no-more-text {

  display: block;

  width: 150px;

}

.more-tip,

.loading-tip,

.no-more-tip {

  display: flex;

  align-items: center;

  justify-content: center;

  height: 150px;

}

.load-moudle .loading-icon {

  display: inline-flex;

  width: 35px;

  height: 35px;

  background: url('../../assets/loading.png') no-repeat;

  background-size: cover;

  margin-right: 5px;

  animation: rotating 2s linear infinite;

}

@keyframes rotating {

  0% {

    transform: rotate(0deg);

  }

  100% {

    transform: rotate(1turn);

  }

}

.connecting-line {

  display: inline-flex;

  width: 150px;

  height: 2px;

  background: #ddd;

  margin-left: 20px;

  margin-right: 20px;

}

</style>



在父组件---引入使用:

<v-reload

        :on-infinite-load="onInfiniteLoad"

        :parent-pull-up-state="infiniteLoadData.pullUpState"

      >

<''列表内容‘’>

</v-reload>

data(){

return{

infiniteLoadData: {

      initialShowNum: 3, // 初始显示多少条

      everyLoadingNum: 3, // 每次加载的个数

      pullUpState: 2, // 子组件的pullUpState状态

      pullUpList: [], // 上拉加载更多数据的数组

      showPullUpListLength: this.initialShowNum // 上拉加载后所展示的个数

    },

}


merhods:{

onInfiniteLoad (done) {

      console.log(done, this.infiniteLoadData.pullUpState)

      if (this.infiniteLoadData.pullUpState === 1) {

        this.getSiteInfo()    //获取列表数据的函数

      }

      done()

    }

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,627评论 6 517
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 95,180评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 169,346评论 0 362
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,097评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,100评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,696评论 1 312
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,165评论 3 422
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,108评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,646评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,709评论 3 342
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,861评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,527评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,196评论 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,698评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,804评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,287评论 3 379
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,860评论 2 361