Skip to content

v-pull-refresh

Implement pull-to-refresh functionality for mobile apps. Triggers refresh action when user pulls down.

Since: 1.3.0

Usage

Basic

vue
<template>
  <div v-pull-refresh="refresh" class="content">
    <div v-if="refreshing" class="loading">Refreshing...</div>
    <ul>
      <li v-for="item in items" :key="item.id">{{ item.name }}</li>
    </ul>
  </div>
</template>

<script setup>
const refreshing = ref(false)

async function refresh(done) {
  refreshing.value = true
  await fetchData()
  refreshing.value = false
  done()
}
</script>

With Options

vue
<template>
  <div v-pull-refresh="{
    handler: refresh,
    threshold: 80,
    loadingText: 'Loading...'
  }">
    Pull down to refresh
  </div>
</template>

API

Types

typescript
interface PullRefreshOptions {
  handler: (done: () => void) => void | Promise<void>
  threshold?: number // default: 60
  disabled?: boolean // default: false
  pullDistance?: number // default: 60
  loadingText?: string
  pullingText?: string
  loosingText?: string
}

Options

OptionTypeDefaultDescription
handler(done) => void | Promise<void>-Refresh handler (required)
thresholdnumber60Distance to trigger refresh
disabledbooleanfalseDisable pull-to-refresh
pullDistancenumber60Max pull distance
loadingTextstring'Loading...'Text while loading
pullingTextstring'Pull to refresh'Text while pulling
loosingTextstring'Release to refresh'Text when threshold reached

Examples

List Refresh

vue
<template>
  <div
    v-pull-refresh="{ handler: refresh, threshold: 80 }"
    class="scroll-container"
  >
    <div v-for="item in items" :key="item.id" class="item">
      {{ item.name }}
    </div>
  </div>
</template>

<script setup>
const items = ref([])

async function refresh(done) {
  const newItems = await fetch('/api/items')
  items.value = newItems
  done()
}
</script>

Custom Indicator

vue
<template>
  <div v-pull-refresh="{
    handler: refresh,
    pullingText: '下拉刷新',
    loosingText: '释放刷新',
    loadingText: '刷新中...'
  }">
    Custom Chinese text
  </div>
</template>

Composable API

For programmatic use, you can use the usePullRefresh composable:

typescript
import { usePullRefresh } from 'directix'

const {
  state,
  distance,
  isPulling,
  events,
  containerRef,
  refresh
} = usePullRefresh({
  handler: async () => {
    await fetchData()
  },
  distance: 60,
  maxDistance: 100,
  disabled: false,
  successDuration: 500,
  errorDuration: 1000
})

// Manually trigger refresh
await refresh()

UsePullRefreshOptions

OptionTypeDefaultDescription
handler() => Promise<void> | void-Refresh handler (required)
distancenumber | Ref<number>60Distance threshold to trigger
maxDistancenumber | Ref<number>100Maximum pull distance
disabledboolean | Ref<boolean>falseDisable pull-to-refresh
successDurationnumber | Ref<number>500Duration to show success indicator
errorDurationnumber | Ref<number>1000Duration to show error indicator

UsePullRefreshReturn

PropertyTypeDescription
stateRef<PullRefreshState>Current state ('idle' | 'pulling' | 'ready' | 'loading' | 'success' | 'error')
distanceRef<number>Current pull distance
isPullingRef<boolean>Whether currently pulling
eventsobjectEvent handlers to bind
containerRefRef<HTMLElement | null>Container ref
refresh() => Promise<void>Manually trigger refresh

Example

vue
<script setup>
import { usePullRefresh } from 'directix'

const { state, distance, events, containerRef } = usePullRefresh({
  handler: async () => {
    await fetchData()
  },
  distance: 80
})
</script>

<template>
  <div
    ref="containerRef"
    @touchstart="events.touchstart"
    @touchmove="events.touchmove"
    @touchend="events.touchend"
  >
    <div class="indicator" :style="{ transform: `translateY(${distance}px)` }">
      {{ state }}
    </div>
    <slot></slot>
  </div>
</template>

Code Generator

Quick Code Generator
<template>
  <div v-pull-refresh>
    <!-- Implement pull-to-refresh functionality for mobile apps. Triggers refresh action when user pulls down. directive -->
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

// Configure your options here
const options = {}
</script>

Released under the MIT License.