SoFunction
Updated on 2025-04-06

Refresh pull-up loading component based on vue package pull-down

Pull-down refresh loading component based on vue and native javascript encapsulation is for your reference. The specific content is as follows

  • The upTilte slot is where the custom content is placed by pull-down refresh
  • The downTilte slot is where the custom content loaded by pulling up is placed
  • The default slot is the list content area

The component code is as follows

<template>
  <div class="refresh" >
    <slot name="upTilte"></slot>
    <slot></slot>
    <slot name="downTilte"></slot>
  </div>
</template>

<script>
export default {
  name: 'PullupOrPulldownRefresh',
  props: {
    // Maximum moving distance    maxMove: {
      type: Number,
      default: 300
    },
    // Damping coefficient    friction: {
      type: Number,
      default: 0.3
    }
  },
  data() {
    return {
      startY: 0,
      ul: null,
      draw: null,
      up: null,
      down: null,
      y: 0 // The distance of inertial rebound    }
  },
  mounted() {
    this.$nextTick(() => {
       = ('refresh')
       = [1]
       = [0]
       = [2]
      ('touchstart', )
      ('touchmove', )
      ('touchend', )
    })
  },
  methods: {
    // Touch start event    touchstart(event) {
       = [0].clientY
    },
    // Touch the mobile event    touchmoveEvent(event) {
      const height =  - 
      if (height ===  ||  === 0) {
        var a = [0].clientY - 
         = a <=  ? a : 
        // In order to clear the lag problem, the transition effect needs to be cleared         = 'none'
         = 'translateY(' +  *  + 'px)'
        // Modify status        const upHeight = - +  * 
        // Pull down to start        if ( *  > 0) (( * ),  = 'none',  = 'translateY(' + upHeight + 'px) translateX(-50%)')
        // Pull-up start        if ( *  < 0) (( * ),  = 'none',  =  *  + 'px')
      }
    },
    // Touch end event    touchendEvent(event) {
      if ( *  >= 50) this.$emit('RefreshUp',  * )
      else if ( *  < -50) this.$emit('RefreshDown',  * )
      else ()
    },
    // Reset and add transition effects    resetStyle() {
       = 'transform .6s'
       = 'translateY(' + 0 + 'px)'
       = 'all .6s'
       = 'translateY(-' +  + 'px) translateX(-50%)'
       = 'all .6s'
       = - + 'px'
    },
    // Set refresh status    setStatus(y) {
      this.$emit('setStatus', y)
    }
  }
}
</script>

<style lang="scss">
.refresh {
  width: 100%;
  height: 100vh;
  border: 2px solid #ccc;
  position: relative;
  overflow: hidden;
  overflow: auto;
  position: fixed;
  ul {
    zoom: 1;
    padding: 0 10%;
  }

  ul::after {
    content: '';
    display: block;
    visibility: hidden;
    height: 0;
    clear: both;
  }

  li {
    list-style: none;
    width: 100%;
    height: 50px;
    line-height: 50px;
    text-align: center;
  }
  .UpRefresh {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    z-index: -9;
  }
  .DownRefresh {
    position: relative;
    left: 50%;
    transform: translateX(-50%);
    margin-top: -10px;
    z-index: -9;
  }
}
</style>
  • How to use components
  • friction is the coefficient of friction
  • @RefreshUp triggers an event for pulling down to a certain distance
  • @RefreshDown triggers the event for pulling up to a certain distance
  • @setStatus is a way to change the refresh state
<template>
  <div>
    <PullupOrPulldownRefresh
      ref="PullupOrPulldownRefresh"
      :maxMove="maxMove"
      :friction="friction"
      @RefreshUp="RefreshUp"
      @RefreshDown="RefreshDown"
      @setStatus="setStatus"
    >
      <template v-slot:upTilte>
        <!-- <div class="UpRefresh" v-show="isUpRefresh">{{ Uptitle }}</div> -->
        <div class="UpRefresh" v-show="isUpRefresh">
          <img :src="require('@/assets/')" alt="" />
          <p>{{ Uptitle }}</p>
        </div>
      </template>
      <ul>
        <li
          v-for="(item, index) in data"
          :key="index"
          style="background: orange"
        >
          {{ item }}
        </li>
      </ul>
      <template v-slot:downTilte>
        <div class="DownRefresh" v-show="isDownRefresh">{{ Downtitle }}</div>
      </template>
    </PullupOrPulldownRefresh>
  </div>
</template>

<script>
export default {
  data() {
    return {
      maxMove: 300,
      friction: 0.3,
      data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
      isUpRefresh: false,
      isDownRefresh: false,
      Downtitle: 'Pull-up Load More',
      Uptitle: 'Drive down to refresh'
    }
  },
  methods: {
    setStatus(y) {
      if (y && y > 0) {
         = true
         = 'Drive down to refresh'
        if (y >= 50)  = 'Refresh with your hands'
        return
      }
       = true
       = 'Pull-up Load More'
      if (y <= -50)  = 'Release Load More'
    },
    RefreshUp(y) {
      if (!y) return
      if (y >= 50) {
         = 'Refreshing'
        setTimeout(() => {
          for (var i = 1; i <= 10; i++) {
            ([ - 1] + 1)
          }
          this.$() // Recovery reset        }, 1000)
      }
    },
    RefreshDown(y) {
      if (!y) return
      if (y <= -50) {
         = 'Loading'
        setTimeout(() => {
          for (var i = 1; i <= 10; i++) {
            ([ - 1] + 1)
          }
          this.$() // Recovery reset        }, 1000)
      }
    }
  }
}
</script>

<style scoped lang="scss">
.UpRefresh img{
  width: 30px;
}
</style>

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.