当前位置:首页 > 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
    安装:

    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属性提升动画性能:

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

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

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

vue实现下拉刷新组件

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

相关文章

vue实现签名

vue实现签名

实现Vue签名功能的步骤 安装签名库 使用vue-signature库可以快速实现签名功能。通过npm或yarn安装: npm install vue-signature --save # 或 y…

vue实现sql操作

vue实现sql操作

在Vue中实现SQL操作通常需要结合后端服务或本地数据库技术,因为前端JavaScript无法直接连接SQL数据库。以下是几种常见的实现方式: 通过API与后端交互 Vue前端通过HTTP请求(如a…

vue如何实现冒泡

vue如何实现冒泡

Vue 实现冒泡排序 在 Vue 中实现冒泡排序,可以通过数据绑定和响应式特性动态展示排序过程。以下是一个完整的实现示例,包含代码和详细说明。 数据准备 在 Vue 的 data 中定义一个数组作为…

vue实现好评弹框

vue实现好评弹框

Vue 实现好评弹框的方法 使用 Vue 实现好评弹框可以通过组件化方式完成,结合动态数据绑定和事件处理。以下是具体实现步骤: 1. 创建弹框组件 新建一个 RatingDialog.vue 组件…

vue页面分离的实现

vue页面分离的实现

Vue页面分离的实现方法 将Vue页面分离为多个组件或模块,有助于提升代码可维护性和复用性。以下是几种常见的实现方式: 组件化拆分 通过将页面拆分为多个子组件,每个组件负责特定功能或UI部分。使用…

vue搜索过后实现分页

vue搜索过后实现分页

Vue 实现搜索后分页功能 数据绑定与搜索逻辑 在 Vue 组件中定义必要的数据属性: data() { return { searchQuery: '', currentPag…