SoFunction
Updated on 2025-04-06

Implementing pull-up loading function based on vue2

This article shares the specific code displayed by vue2 implementation pull-up loading for your reference. The specific content is as follows

Because we also use swiper in our project. Many of them are switched by sliding, but they have to be loaded up, which leads to different bugs in many UI frameworks that we used. There is no way, so we finally wrote one. The code is as follows (because this can be used in many places, it is recommended to put it under 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: 'Pull-up refresh'
      },
      bottomDropText: {
        type: String,
        default: 'Release update'
      },
      bottomLoadingText: {
        type: String,
        default: 'loading...'
      },
      bottomDistance: {
        type: Number,
        default: 70
      },
      bottomMethod: {
        type: Function
      },
      bottomAllLoaded: {
        type: Boolean,
        default: false
      },
    },
    data() {
      return {
        // The displacement of the div that appears at the bottom        translate: 0,
        // Select the listener object for the scroll event        scrollEventTarget: null,
        containerFilled: false,
        bottomText: '',
        // class class name        bottomDropped: false,
        // Get the scrollTop for listening to scroll elements        bottomReached: false,
        // Sliding direction down----interaction down; up---slide up        direction: '',
        startY: 0,
        startScrollTop: 0,
        // Real-time clientY location        currentY: 0,
        topStatus: '',
        // Pull-up loading status '' pull: Pull-up        bottomStatus: '',
      };
    },
    watch: {
      // Change the current loading state      bottomStatus(val) {
        this.$emit('bottom-status-change', val);
        switch (val) {
          case 'pull':
             = ;
            break;
          case 'drop':
             = ;
            break;
          case 'loading':
             = ;
            break;
        }
      }
    },
    methods: {
      onBottomLoaded() {
         = 'pull';
         = false;
        this.$nextTick(() => {
          if ( === window) {
           += 50;
        } else {
           += 50;
        }
         = 0;
      });
        // Comments        if (! && !) {
          ();
        }
      },

      getScrollEventTarget(element) {
        let currentNode = element;
        while (currentNode &&  !== 'HTML' &&
         !== 'BODY' &&  === 1) {
          let overflowY = (currentNode).overflowY;
          if (overflowY === 'scroll' || overflowY === 'auto') {
            return currentNode;
          }
          currentNode = ;
        }
        return window;
      },
      // Get scrollTop      getScrollTop(element) {
        if (element === window) {
          return ( || 0, );
        } else {
          return ;
        }
      },
      bindTouchEvents() {
        this.$('touchstart', );
        this.$('touchmove', );
        this.$('touchend', );
      },
      init() {
         = 'pull';
        // Select the listener object for the scroll event         = (this.$el);
        if (typeof  === 'function') {
          // Implementation of autoFill attribute comment          ();
          // Bind sliding event          ();
        }
      },
      // Implementation of autoFill attribute comment      fillContainer() {
        if () {
          this.$nextTick(() => {
            if ( === window) {
             = this.$().bottom >=
                ().bottom;
          } else {
             = this.$().bottom >=
                ().bottom;
          }
          if (!) {
             = 'loading';
            ();
          }
        });
        }
      },
      // Get the scrollTop for listening to scroll elements      checkBottomReached() {
        if ( === window) {
          return  +  >= ;
        } else {
          // getBoundingClientRect is used to get the left, upper, right and lower positions of an element in the page relative to the browser window respectively.  right refers to the distance between the right boundary of the element from the leftmost window, bottom refers to the distance between the lower boundary of the element from the topmost window.          return this.$().bottom <= ().bottom + 1;
        }
      },
      // ontouchstart event      handleTouchStart(event) {
        // Get the y-coordinate of the starting point         = [0].clientY;
         = ();
         = false;
        if ( !== 'loading') {
           = 'pull';
           = false;
        }
      },
      // ontouchmove event      handleTouchMove(event) {
        if ( < this.$().top &&  > this.$().bottom) {
          // No scrolling within the range that needs to be scrolled, no longer listening to scroll          return;
        }
        // Real-time clientY location         = [0].clientY;
        // distance The difference between the moving position and the starting position distanceIndex---        let distance = ( - ) / ;
        //Judge the direction of sliding according to distance and assign variable direction down---down interaction; up---up         = distance > 0 ? 'down' : 'up';
        if ( === 'up') {
          // Get the scrollTop for listening to scroll elements           =  || ();
        }
        if (typeof  === 'function' &&  === 'up' &&
             &&  !== 'loading' && !) {
          // There is a loading function, it is pulling up, there is a scrolling distance, it is not loading ajax, it is not loading to the last page          ();
          ();
          if ( > 0) {
             = (distance) <= 
                ? () -  + distance : ;
          } else {
             = () -  + distance;
          }
          if ( > 0) {
             = 0;
          }
           = - >=  ? 'drop' : 'pull';
        }
      },
      // ontouchend event      handleTouchEnd() {
        if ( === 'up' &&  &&  < 0) {
           = true;
           = false;
          if ( === 'drop') {
             = '-50';
             = 'loading';
            ();
          } else {
             = '0';
             = 'pull';
          }
        }
         = '';
      }
    },
    mounted() {
      ();
    }
  };
</script>

Then import which page is needed and which page you want: import LoadMore from './../common/'; When it is needed, write the following:

<template>
 <section class="finan">
  <!-- Pull-up load more -->
  <load-more
  :bottom-method="loadBottom"
  :bottom-all-loaded="allLoaded"
  :bottomPullText='bottomText'
  :auto-fill="false"
  @bottom-status-change="handleBottomChange"
  ref="loadmore">
    <div>
  Here are the additional modules you need
    </div>
    <div v-show="loading" slot="bottom" class="loading"> thisdivIt is to let a loading picture be displayed when the pull-up is loaded.gifpicture
     <img src="./../../assets/main/">
    </div>
  </load-more>
 </section>
</template>

Then the data and methods are set as follows:

  export default {
    name: 'FinancialGroup',
    props:{
 
    },
    data () {
      return {
        // Pull up to load data        scrollHeight: 0,
        scrollTop: 0,
        containerHeight: 0,
        loading: false,
        allLoaded: false,
        bottomText: 'Pull-up load more...',
        bottomStatus: '',
        pageNo: 1,
        totalCount: '',
      }
    },
    methods: {
    /* Pull down to load */
    _scroll: function(ev) {
      ev = ev || event;
       = this.$;
       = this.$;
       = this.$;
    },
    loadBottom: function() {
       = true;
       += 1;  // Number of pages loaded each time      if ( == ) {
        // Pull-up loading stops when allLoaded = true         = false;
         = true;
      }
      (Backend interface,Request parameters) thisapiIt's encapsulatedaxiosIf you don't understand, you can read itvue2+vuex+axiosThat article
          .then(res => {
        setTimeout(() => {
      The data returned by the background to be used is written insetTimeoutin
         this.$nextTick(() => {
           = false;
        })
      }, 1000)
     });
    },
    handleBottomChange(status) {
       = status;
    },
  }

This is done.

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.