当前位置:首页 > 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增删改查简单实现

基础环境搭建 确保已安装Node.js和Vue CLI。通过以下命令创建Vue项目: npm install -g @vue/cli vue create vue-crud-demo cd vue…

vue实现页面截屏

vue实现页面截屏

使用html2canvas库实现截屏 html2canvas是一个流行的JavaScript库,可以将DOM元素转换为Canvas图像。在Vue项目中安装html2canvas: npm inst…

vue实现弹窗可切换

vue实现弹窗可切换

实现弹窗可切换的 Vue 方案 动态组件切换 通过 Vue 的 <component :is="currentComponent"> 动态加载不同弹窗组件,结合 v-if 控制显示状态。…

vue无限菜单怎么实现

vue无限菜单怎么实现

实现 Vue 无限菜单的方法 递归组件实现嵌套菜单 使用 Vue 的递归组件特性可以轻松实现无限级嵌套菜单。通过组件调用自身的方式处理嵌套数据。 <template> <ul&…

vue实现自定义登录

vue实现自定义登录

实现自定义登录的基本步骤 在Vue中实现自定义登录功能通常需要结合前端和后端技术。以下是一个基本的实现流程: 创建登录表单组件 使用Vue的单文件组件创建一个登录表单,包含用户名和密码输入框以及提…

vue实现画圆弧并着色

vue实现画圆弧并着色

在 Vue 中实现画圆弧并着色 使用 Canvas API 绘制圆弧 在 Vue 组件的 mounted 钩子中,通过 Canvas API 绘制圆弧。创建一个 canvas 元素并获取其上下文:…