当前位置: 移动技术网 > IT编程>脚本编程>vue.js > 基于vue2实现上拉加载功能

基于vue2实现上拉加载功能

2017年12月08日  | 移动技术网IT编程  | 我要评论

spanking资源交流站,泸州个人二手房网,现金娱乐平台

本文实例为大家分享了vue2实现上拉加载展示的具体代码,供大家参考,具体内容如下

因为我们项目中,还用了swiper。很多都是滑动切换的,但是又得上拉加载,所以导致,很多ui框架,我们用了,都有不同的bug出现,没办法,最后写了一个。代码如下(这个因为很多地方会用,所以建议放在components/common下面):

<template>
  <div class="loadmore">
    <slot></slot>
    <slot name="bottom">
    </slot>
  </div>
</template>

<style>
  .loadmore{
    width:100%;
  }
</style>

<script>
  export default {
    name: 'loadmore',
    props: {
      maxdistance: {
        type: number,
        default: 0
      },
      autofill: {
        type: boolean,
        default: true
      },
      distanceindex: {
        type: number,
        default: 2
      },
      bottompulltext: {
        type: string,
        default: '上拉刷新'
      },
      bottomdroptext: {
        type: string,
        default: '释放更新'
      },
      bottomloadingtext: {
        type: string,
        default: '加载中...'
      },
      bottomdistance: {
        type: number,
        default: 70
      },
      bottommethod: {
        type: function
      },
      bottomallloaded: {
        type: boolean,
        default: false
      },
    },
    data() {
      return {
        // 最下面出现的div的位移
        translate: 0,
        // 选择滚动事件的监听对象
        scrolleventtarget: null,
        containerfilled: false,
        bottomtext: '',
        // class类名
        bottomdropped: false,
        // 获取监听滚动元素的scrolltop
        bottomreached: false,
        // 滑动的方向  down---向下互动;up---向上滑动
        direction: '',
        starty: 0,
        startscrolltop: 0,
        // 实时的clienty位置
        currenty: 0,
        topstatus: '',
        // 上拉加载的状态  ''   pull: 上拉中
        bottomstatus: '',
      };
    },
    watch: {
      // 改变当前加载在状态
      bottomstatus(val) {
        this.$emit('bottom-status-change', val);
        switch (val) {
          case 'pull':
            this.bottomtext = this.bottompulltext;
            break;
          case 'drop':
            this.bottomtext = this.bottomdroptext;
            break;
          case 'loading':
            this.bottomtext = this.bottomloadingtext;
            break;
        }
      }
    },
    methods: {
      onbottomloaded() {
        this.bottomstatus = 'pull';
        this.bottomdropped = false;
        this.$nexttick(() => {
          if (this.scrolleventtarget === window) {
          document.body.scrolltop += 50;
        } else {
          this.scrolleventtarget.scrolltop += 50;
        }
        this.translate = 0;
      });
        // 注释
        if (!this.bottomallloaded && !this.containerfilled) {
          this.fillcontainer();
        }
      },

      getscrolleventtarget(element) {
        let currentnode = element;
        while (currentnode && currentnode.tagname !== 'html' &&
        currentnode.tagname !== 'body' && currentnode.nodetype === 1) {
          let overflowy = document.defaultview.getcomputedstyle(currentnode).overflowy;
          if (overflowy === 'scroll' || overflowy === 'auto') {
            return currentnode;
          }
          currentnode = currentnode.parentnode;
        }
        return window;
      },
      // 获取scrolltop
      getscrolltop(element) {
        if (element === window) {
          return math.max(window.pageyoffset || 0, document.documentelement.scrolltop);
        } else {
          return element.scrolltop;
        }
      },
      bindtouchevents() {
        this.$el.addeventlistener('touchstart', this.handletouchstart);
        this.$el.addeventlistener('touchmove', this.handletouchmove);
        this.$el.addeventlistener('touchend', this.handletouchend);
      },
      init() {
        this.bottomstatus = 'pull';
        // 选择滚动事件的监听对象
        this.scrolleventtarget = this.getscrolleventtarget(this.$el);
        if (typeof this.bottommethod === 'function') {
          // autofill 属性的实现  注释
          this.fillcontainer();
          // 绑定滑动事件
          this.bindtouchevents();
        }
      },
      // autofill 属性的实现  注释
      fillcontainer() {
        if (this.autofill) {
          this.$nexttick(() => {
            if (this.scrolleventtarget === window) {
            this.containerfilled = this.$el.getboundingclientrect().bottom >=
                document.documentelement.getboundingclientrect().bottom;
          } else {
            this.containerfilled = this.$el.getboundingclientrect().bottom >=
                this.scrolleventtarget.getboundingclientrect().bottom;
          }
          if (!this.containerfilled) {
            this.bottomstatus = 'loading';
            this.bottommethod();
          }
        });
        }
      },
      // 获取监听滚动元素的scrolltop
      checkbottomreached() {
        if (this.scrolleventtarget === window) {
          return document.body.scrolltop + document.documentelement.clientheight >= document.body.scrollheight;
        } else {
          // getboundingclientrect用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置。 right是指元素右边界距窗口最左边的距离,bottom是指元素下边界距窗口最上面的距离。
          return this.$el.getboundingclientrect().bottom <= this.scrolleventtarget.getboundingclientrect().bottom + 1;
        }
      },
      // ontouchstart 事件
      handletouchstart(event) {
        // 获取起点的y坐标
        this.starty = event.touches[0].clienty;
        this.startscrolltop = this.getscrolltop(this.scrolleventtarget);
        this.bottomreached = false;
        if (this.bottomstatus !== 'loading') {
          this.bottomstatus = 'pull';
          this.bottomdropped = false;
        }
      },
      // ontouchmove事件
      handletouchmove(event) {
        if (this.starty < this.$el.getboundingclientrect().top && this.starty > this.$el.getboundingclientrect().bottom) {
          // 没有在需要滚动的范围内滚动,不再监听scroll
          return;
        }
        // 实时的clienty位置
        this.currenty = event.touches[0].clienty;
        // distance 移动位置和开始位置的差值    distanceindex---
        let distance = (this.currenty - this.starty) / this.distanceindex;
        // 根据 distance 判断滑动的方向 并赋予变量  direction down---向下互动;up---向上滑动
        this.direction = distance > 0 ? 'down' : 'up';
        if (this.direction === 'up') {
          // 获取监听滚动元素的scrolltop
          this.bottomreached = this.bottomreached || this.checkbottomreached();
        }
        if (typeof this.bottommethod === 'function' && this.direction === 'up' &&
            this.bottomreached && this.bottomstatus !== 'loading' && !this.bottomallloaded) {
          // 有加载函数,是向上拉,有滚动距离,不是正在加载ajax,没有加载到最后一页
          event.preventdefault();
          event.stoppropagation();
          if (this.maxdistance > 0) {
            this.translate = math.abs(distance) <= this.maxdistance
                ? this.getscrolltop(this.scrolleventtarget) - this.startscrolltop + distance : this.translate;
          } else {
            this.translate = this.getscrolltop(this.scrolleventtarget) - this.startscrolltop + distance;
          }
          if (this.translate > 0) {
            this.translate = 0;
          }
          this.bottomstatus = -this.translate >= this.bottomdistance ? 'drop' : 'pull';
        }
      },
      // ontouchend事件
      handletouchend() {
        if (this.direction === 'up' && this.bottomreached && this.translate < 0) {
          this.bottomdropped = true;
          this.bottomreached = false;
          if (this.bottomstatus === 'drop') {
            this.translate = '-50';
            this.bottomstatus = 'loading';
            this.bottommethod();
          } else {
            this.translate = '0';
            this.bottomstatus = 'pull';
          }
        }
        this.direction = '';
      }
    },
    mounted() {
      this.init();
    }
  };
</script>

然后哪个页面需要,在哪个页面导入即可:import loadmore from './../common/loadmore.vue';在需要引入他的页面写法如下:

<template>
 <section class="finan">
  <!-- 上拉加载更多 -->
  <load-more
  :bottom-method="loadbottom"
  :bottom-all-loaded="allloaded"
  :bottompulltext='bottomtext'
  :auto-fill="false"
  @bottom-status-change="handlebottomchange"
  ref="loadmore">
    <div>
  这里写你需要的另外的模块
    </div>
    <div v-show="loading" slot="bottom" class="loading"> 这个div是为让上拉加载的时候显示一张加载的gif图
     <img src="./../../assets/main/uploading.gif">
    </div>
  </load-more>
 </section>
</template>

然后在此页面的data里和methods设置如下:

  export default {
    name: 'financialgroup',
    props:{
 
    },
    data () {
      return {
        // 上拉加载数据
        scrollheight: 0,
        scrolltop: 0,
        containerheight: 0,
        loading: false,
        allloaded: false,
        bottomtext: '上拉加载更多...',
        bottomstatus: '',
        pageno: 1,
        totalcount: '',
      }
    },
    methods: {
    /* 下拉加载 */
    _scroll: function(ev) {
      ev = ev || event;
      this.scrollheight = this.$refs.innerscroll.scrollheight;
      this.scrolltop = this.$refs.innerscroll.scrolltop;
      this.containerheight = this.$refs.innerscroll.offsetheight;
    },
    loadbottom: function() {
      this.loading = true;
      this.pageno += 1;  // 每次更迭加载的页数
      if (this.pageno == this.totalgetcount) {
        // 当allloaded = true时上拉加载停止
        this.loading = false;
        this.allloaded = true;
      }
      api.commonapi(后台接口,请求参数) 这个api是封装的axios有不懂的可以看vue2+vuex+axios那篇文章
          .then(res => {
        settimeout(() => {
      要使用的后台返回的数据写在settimeout里面
         this.$nexttick(() => {
          this.loading = false;
        })
      }, 1000)
     });
    },
    handlebottomchange(status) {
      this.bottomstatus = status;
    },
  }

这样就完成了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网