Skip to content

Usage

Playground

Interactive sandbox for VueEasyPullRefresh. Toggle any prop on the left and pull down inside the preview on the right to see the result. Event counters show how many times reached and settled have fired.


Basic example

The smallest possible usage. Pull down inside the preview — the timestamp and session badge update so you can see the refresh happen. Each preview on this page contains a ⬇ Pull down ⬇ hint: the gesture works with the mouse too (press-drag).

Show code
vue
<template>
    <VueEasyPullRefresh>
        <!-- content -->
    </VueEasyPullRefresh>
</template>

Nested horizontal swipers

A directionLockAngle prop (default 30°) keeps horizontal gestures (carousels, tabs, sliders) from triggering a pull. Swipe the strip horizontally — the loader stays hidden. Pull straight down on the background to refresh.

Compare the default (30°) vs. a relaxed (60°) vs. disabled (90°) lock — the wider the angle, the more off-vertical a gesture can be before it still counts as a pull.

Show code
vue
<template>
    <VueEasyPullRefresh :direction-lock-angle="30">
        <!-- carousels, tabs, horizontal sliders -->
    </VueEasyPullRefresh>
</template>

pullDownThreshold

Distance the user must pull before a refresh fires. Try both — the right one fires only after a longer drag.

Show code
vue
<template>
    <VueEasyPullRefresh :pull-down-threshold="40" />
    <VueEasyPullRefresh :pull-down-threshold="120" />
</template>

isAppearAnimation

Controls the fade-in of the refreshed content. Pull both and compare — the right one swaps without animation.

Show code
vue
<template>
    <VueEasyPullRefresh />
    <VueEasyPullRefresh :is-appear-animation="false" />
</template>

isFreezeContent

Defers the content swap until the loader is fully hidden. Pull both — on the left the new content fades in while the loader is still rolling up; on the right the old content stays put until the loader disappears, then the new content appears.

Show code
vue
<template>
    <VueEasyPullRefresh />
    <VueEasyPullRefresh :is-freeze-content="true" />
</template>

isRefreshContent

When true (default), the slot is re-keyed on every refresh so its child components re-mount. When false, the slot stays in place and you update data yourself via the queue.

In both previews the data still updates because the demo content registers a task via pullDownQueueAdd. On the left the whole slot also re-mounts; on the right the same instance keeps running.

Show code
vue
<template>
    <VueEasyPullRefresh />
    <VueEasyPullRefresh :is-refresh-content="false" />
</template>

isDisabled

Turns the gesture off completely — no pull, no loader, no refresh.

Show code
vue
<template>
    <VueEasyPullRefresh :is-disabled="true" />
</template>

Custom loader

Replace the default spinner via the loader slot.

Show code
vue
<template>
    <VueEasyPullRefresh>
        <template #loader>
            <!-- custom loader -->
        </template>
        <!-- content -->
    </VueEasyPullRefresh>
</template>

initialQueue

Pass a refresh callback as a prop. It runs every time the gesture completes, before the loader hides. The preview below waits 1.2 s to resolve.

Show code
vue
<template>
    <VueEasyPullRefresh :initial-queue="someRequest">
        <!-- content -->
    </VueEasyPullRefresh>
</template>

<script setup>
function someRequest() {
    return new Promise(resolve => {
        setTimeout(resolve, 1200, true);
    });
}
</script>

Queue from a child component

Descendants can register async tasks on the same refresh via useEasyPullRefresh().pullDownQueueAdd. All tasks run in parallel; the loader stays visible until the slowest one resolves. Pull the preview below — Child A (600 ms) lands first, Child B (3000 ms) lands later, and only then does the loader roll up.

Show code
vue
<!-- parent -->
<template>
    <VueEasyPullRefresh :is-refresh-content="false">
        <ChildA />
        <ChildB />
    </VueEasyPullRefresh>
</template>
vue
<!-- ChildA.vue -->
<script setup>
import { useEasyPullRefresh } from 'vue-easy-pull-refresh';

const { pullDownQueueAdd } = useEasyPullRefresh();

pullDownQueueAdd(() => fetch('/api/feed').then(r => r.json()));
</script>
vue
<!-- ChildB.vue -->
<script setup>
import { useEasyPullRefresh } from 'vue-easy-pull-refresh';

const { pullDownQueueAdd } = useEasyPullRefresh();

pullDownQueueAdd(() => fetch('/api/notifications').then(r => r.json()));
</script>

Callbacks registered this way are automatically removed when their component unmounts.


Deprecated: ref-based controlled refresh

Deprecated

This approach is deprecated starting from version 1.1.3. Use the initialQueue prop or queue from a child component instead.

Older versions exposed the queue through a template ref. It still works but new code should prefer the patterns above.

Show code
vue
<template>
    <VueEasyPullRefresh
        ref="refRefresh"
        :is-refresh-content="false"
    >
        <!-- content -->
    </VueEasyPullRefresh>
</template>

<script setup>
import { useEasyPullRefresh } from 'vue-easy-pull-refresh';

const { refRefresh, pullDownQueueAdd } = useEasyPullRefresh();

pullDownQueueAdd(() => Promise.resolve());
</script>