SoFunction
Updated on 2025-04-04

vue loadmore component sliding load more source code analysis

Previous articleWhen it comes to using pull-up loading more components in projects, but due to changes in actual project development, some models will also pull up the webview together when pulling up, resulting in insensitive loading, etc., we sometimes change to the function of sliding to the bottom to automatically load.

Since they all load more, many code ideas are bound to be similar. The main difference is the operation of pulling up and sliding to the bottom, so we need to pay attention to:

Pull-up loading is a point pointer touch touch event. Now, because it is sliding loading, you need to add a scroll event to listen and execute the corresponding callback.

Pull-up loading mainly calculates the touch scroll distance, while sliding loading mainly calculates the distance between the bottom of the container and the upper edge of the window

Change the event binding to:

 mounted() {
  ···
  ('scroll', , false)
  ···
 },
 beforeDestroy() {
  ···
  ('scroll', , false)
  ···
 },

Change the event callback to:

 /**
   * Rolling hook
   */
  scroll() {
  const viewHeight = 
  let parentNode
  if ( !== global) {
   parentNode = this.$el
  } else {
   parentNode = this.$
  }
  if (parentNode) {
   // Get the position of the root DOM element used by the Vue instance relative to the viewport   const rect = ()
   // How far from the bottom start loading   // If the distance between the bottom edge of this element from the top of the viewport is less than the sum of the height of the viewport plus distance, the next page will be loaded   if (( <= viewHeight + ) &&  && !) {
   ()
   }
  }
  },

The source code is as follows:

<template>
 <div class="loadmore" ref="loadmore">
 <div class="loadmore__body">
  <slot></slot>
 </div>
 <div class="loadmore__footer">
  <span v-if="loading">
  <i class="tc-loading"></i>
  <span>Loading</span>
  </span>
  <span v-else-if="loadable">Load more</span>
  <span v-else>No more</span>
 </div>
 </div>
</template>
<script type="text/babel">
 import axios from 'axios'
 const CancelToken = 
 export default {
 data() {
  return {
  /**
    * Total number of pages (returned by the server)
    * @type {number}
    */
  count: 0,
  /**
    * Is it dragging or not
    * @type {boolean}
    */
  dragging: false,
  /**
    * Number of loaded times
    * @type {number}
    */
  times: 0,
  /**
    * Recording has begun
    * @type {boolean}
    */
  started: false,
  /**
    * Loading
    * @type {boolean}
    */
  loading: false,
  dom: null,
  }
 },
 props: {
  /**
   * Automatically start loading of data after initialization
   */
  autoload: {
  type: Boolean,
  default: true,
  },
  /**
   * The scrollable parent element closest to the component (used to listen to events and get scroll bar position)
   */
  container: {
  // Selector or Element
  default: () => (global),
  },
  /**
   * Axios request parameter configuration object
   * {@link /mzabriskie/axios#request-config}
   */
  options: {
  type: Object,
  default: null,
  },
  /**
   * Start page number
   */
  page: {
  type: Number,
  default: 1,
  },
  /**
   * Number of data pieces loaded per page
   */
  rows: {
  type: Number,
  default: 10,
  },
  /**
   * Data loading request address
   */
  url: {
  type: String,
  default: '',
  },
  /**
   * How far from the bottom load
   */
  distance: {
  type: Number,
  default: 200,
  },
 },
 computed: {
  /**
   * Is it possible to load
   * @returns {boolean} Yes or no
   */
  loadable() {
  return ! || ( + ) <= 
  },
 },
 mounted() {
  if ( !== global) {
   = ()
  } else {
   = 
  }
  if (!) {
  return
  }
  ('scroll', , false)
  if ( && !) {
  ()
  }
 },
 // eslint-disable-next-line
 beforeDestroy() {
  if () {
  ('scroll', , false)
  }
 },
 methods: {
  /**
   * Rolling hook
   */
  scroll() {
  const viewHeight = 
  let parentNode
  if ( !== global) {
   parentNode = this.$el
  } else {
   parentNode = this.$
  }
  if (parentNode) {
   const rect = ()
   if (( <= viewHeight + ) &&  && !) {
   ()
   }
  }
  },
  /**
   * Methods to load a set of data
   */
  load() {
  if () {
   return
  }
   = true
   = true
  const params = {
   currentPage:  + ,
   pageSize: ,
  }
  const options = ({}, , {
   url: ,
   cancelToken: new CancelToken((cancel) => {
    = cancel
   }),
  })
  if (String().toUpperCase() === 'POST') {
    = ({}, , params)
  } else {
    = ({}, , params)
  }
  this.$(options).then((res) => {
   const data = 
    += 1
    = false
    = 
   this.$emit('success', )
   this.$emit('complete')
  }).catch((e) => {
    = false
   this.$emit('error', e)
   this.$emit('complete')
  })
  },
  /**
   * Reset load related variables
   */
  reset() {
   = 0
   = 0
   = false
   = false
  },
  /**
   *Restart loading
   */
  restart() {
  ()
  ()
  },
 },
 }
</script>

The above is the editor’s introduction to more source code analysis of the vue loadmore component sliding loading. I hope it will be helpful to everyone. If you have any questions, please leave me a message and the editor will reply to everyone in time. Thank you very much for your support for my website!