当前位置:首页 > VUE

vue实现下拉刷新组件

2026-01-07 06:05:30VUE

实现下拉刷新组件的核心思路

下拉刷新功能通常通过监听触摸事件、滚动位置和动画效果实现。Vue中可以利用自定义指令或封装组件完成,以下为两种常见实现方式。

基于自定义指令的实现

创建指令监听触摸事件,计算下拉距离并触发回调:

Vue.directive('pull-to-refresh', {
  bind(el, binding) {
    let startY = 0
    let currentY = 0
    const refreshHeight = 50

    el.addEventListener('touchstart', e => {
      startY = e.touches[0].pageY
    }, { passive: true })

    el.addEventListener('touchmove', e => {
      currentY = e.touches[0].pageY
      const scrollTop = document.documentElement.scrollTop || document.body.scrollTop

      if (scrollTop === 0 && currentY - startY > 0) {
        e.preventDefault()
        const distance = Math.min(currentY - startY, refreshHeight * 3)
        binding.value(distance / refreshHeight)
      }
    }, { passive: false })

    el.addEventListener('touchend', () => {
      if ((currentY - startY) > refreshHeight) {
        binding.value('refresh')
      } else {
        binding.value(0)
      }
    }, { passive: true })
  }
})

使用方式:

<div v-pull-to-refresh="handleRefresh">
  <!-- 内容区域 -->
</div>

封装可复用组件方案

创建独立组件处理所有交互逻辑:

<template>
  <div class="refresh-container" @touchstart="onTouchStart" @touchmove="onTouchMove" @touchend="onTouchEnd">
    <div class="refresh-control" :style="{ transform: `translateY(${pullDistance}px)` }">
      <slot name="loading" v-if="isRefreshing">
        <!-- 自定义加载中状态 -->
      </slot>
      <slot name="pull" v-else>
        <!-- 自定义下拉提示 -->
      </slot>
    </div>
    <slot></slot>
  </div>
</template>

<script>
export default {
  data() {
    return {
      startY: 0,
      currentY: 0,
      pullDistance: 0,
      isRefreshing: false,
      maxPullDistance: 70
    }
  },
  methods: {
    onTouchStart(e) {
      if (this.isRefreshing) return
      this.startY = e.touches[0].pageY
    },
    onTouchMove(e) {
      if (this.isRefreshing) return
      this.currentY = e.touches[0].pageY
      const scrollTop = document.documentElement.scrollTop

      if (scrollTop === 0 && this.currentY - this.startY > 0) {
        this.pullDistance = Math.min(
          this.currentY - this.startY,
          this.maxPullDistance
        )
      }
    },
    onTouchEnd() {
      if (this.pullDistance > this.maxPullDistance * 0.6) {
        this.isRefreshing = true
        this.$emit('refresh')
      } else {
        this.pullDistance = 0
      }
    },
    finishRefresh() {
      this.isRefreshing = false
      this.pullDistance = 0
    }
  }
}
</script>

<style>
.refresh-container {
  position: relative;
}
.refresh-control {
  position: absolute;
  width: 100%;
  top: 0;
  left: 0;
  transition: transform 0.3s ease;
}
</style>

第三方库推荐方案

  1. vue-pull-refresh
    安装:

    vue实现下拉刷新组件

    npm install vue-pull-refresh

    使用示例:

    <template>
      <pull-refresh @refresh="onRefresh">
        <!-- 内容区域 -->
      </pull-refresh>
    </template>
    
    <script>
    import PullRefresh from 'vue-pull-refresh'
    
    export default {
      components: { PullRefresh },
      methods: {
        onRefresh(done) {
          fetchData().then(() => done())
        }
      }
    }
    </script>
  2. mescroll.js
    支持下拉刷新和上拉加载的完整解决方案:

    <template>
      <mescroll-vue ref="mescroll" @down="downCallback" @up="upCallback">
        <!-- 内容列表 -->
      </mescroll-vue>
    </template>

性能优化要点

  • 使用CSS will-change属性提升动画性能:

    vue实现下拉刷新组件

    .refresh-control {
      will-change: transform;
    }
  • 避免频繁的DOM操作,使用transform代替top定位

  • 添加防抖处理快速连续触发

  • 移动端注意passive事件监听器的使用

标签: 组件vue
分享给朋友:

相关文章

vue实现list

vue实现list

Vue 实现列表渲染 在 Vue 中,可以使用 v-for 指令来渲染列表。v-for 指令基于一个数组或对象来渲染一个列表,可以遍历数组或对象的属性。 基本列表渲染 <template>…

vue 实现跳转

vue 实现跳转

Vue 实现页面跳转的方法 在 Vue 中实现页面跳转通常可以通过以下几种方式实现,具体选择取决于项目需求和技术栈(如是否使用 Vue Router)。 使用 Vue Router 进行编程式导航…

vue实现折叠

vue实现折叠

Vue 实现折叠功能 在 Vue 中实现折叠功能可以通过多种方式完成,以下介绍几种常见的方法。 使用 v-show 或 v-if 控制显示隐藏 通过 Vue 的指令 v-show 或 v-if 可以…

vue 实现协同

vue 实现协同

Vue 实现协同编辑的方案 协同编辑指多个用户同时编辑同一文档并实时同步更改。Vue 结合相关库和技术可轻松实现该功能。 使用 WebSocket 实现实时通信 WebSocket 提供全双工通信,…

vue 实现vshow

vue 实现vshow

Vue 实现 v-show 在 Vue 中,v-show 是一个常用的指令,用于根据条件控制元素的显示或隐藏。与 v-if 不同,v-show 不会移除 DOM 元素,而是通过 CSS 的 displ…

vue实现watch

vue实现watch

监听数据变化 在Vue中,watch用于监听响应式数据的变化并执行回调函数。基本语法如下: watch: { propertyName(newValue, oldValue) { //…