Skip to content

useScrollTo

适用于 Vue3Nuxt3HTML

使元素可自定义缓动

示例

纵向缓动

查看代码
vue
<script setup lang="ts">
import { ref } from "vue";
import { faker } from "@faker-js/faker/locale/en";
import { useMessage } from "../../components/message";
import { useScrollTo, debounce } from "@pureadmin/utils";

const scrollRef = ref();
const { message } = useMessage();

// 加个防抖。连续点击,只会执行第一次点击事件,立即执行
const onTop = debounce(
  () =>
    useScrollTo({
      el: scrollRef,
      to: 0,
      directions: "scrollTop",
      duration: 2000,
      callback: msg => {
        msg === "滚动完毕"
          ? message.success("已滚动到顶部")
          : message.info(msg);
      }
    }).start(),
  1200,
  true
);

const onBottom = debounce(
  () =>
    useScrollTo({
      el: scrollRef,
      to: scrollRef.value!.scrollHeight,
      directions: "scrollTop",
      duration: 2000,
      callback: msg => {
        msg === "滚动完毕"
          ? message.success("已滚动到底部")
          : message.info(msg);
      }
    }).start(),
  1200,
  true
);

const onTopShortly = () => {
  useScrollTo({ el: scrollRef, to: 0, directions: "scrollTop" }).start();
};

const onBottomShortly = () => {
  useScrollTo({
    el: scrollRef,
    to: scrollRef.value!.scrollHeight,
    directions: "scrollTop"
  }).start();
};

// 整页滚动
const onPageTop = debounce(
  () =>
    useScrollTo({
      el: document.documentElement,
      to: 0,
      directions: "scrollTop",
      duration: 800,
      callback: msg => {
        msg === "滚动完毕"
          ? message.success("整页已滚动到顶部")
          : message.info(msg);
      }
    }).start(),
  1200,
  true
);

const onPageBottom = debounce(
  () =>
    useScrollTo({
      el: document.documentElement,
      to: document.documentElement.scrollHeight,
      directions: "scrollTop",
      duration: 800,
      callback: msg => {
        msg === "滚动完毕"
          ? message.success("整页已滚动到底部")
          : message.info(msg);
      }
    }).start(),
  1200,
  true
);
</script>

<template>
  <naive-theme>
    <div
      ref="scrollRef"
      class="w-full h-[335px] mt-3 overflow-y-scroll border-solid border-1 border-[var(--vp-c-divider)] rounded-lg"
    >
      <div v-for="(_, index) in 50" :key="index" class="my-[10px]">
        <div class="flex items-center justify-start p-2 w-9/10 ml-3">
          <img
            class="rounded-lg w-[80px] mr-10"
            :src="`https://xiaoxian521.github.io/hyperlink/avatar/400*400_${
              index + 1
            }.jpg`"
          />
          <p>{{ faker.word.words({ count: { min: 5, max: 10 } }) }}</p>
        </div>
      </div>
    </div>
    <n-button tertiary size="small" class="mt-4" @click="onTop">
      滚动到顶部
    </n-button>
    <n-button tertiary size="small" class="mt-4 ml-2" @click="onBottom">
      滚动到底部
    </n-button>
    <br />
    <n-button tertiary size="small" class="mt-2" @click="onTopShortly">
      滚动到顶部(无缓动效果)
    </n-button>
    <n-button tertiary size="small" class="mt-2 ml-2" @click="onBottomShortly">
      滚动到底部(无缓动效果)
    </n-button>
    <br />
    <n-button tertiary size="small" class="mt-2" @click="onPageTop">
      整页滚动到顶部
    </n-button>
    <n-button tertiary size="small" class="mt-2 ml-2" @click="onPageBottom">
      整页滚动到底部
    </n-button>
  </naive-theme>
</template>

横向缓动

查看代码
vue
<script setup lang="ts">
import { ref } from "vue";
import { faker } from "@faker-js/faker/locale/en";
import { useMessage } from "../../components/message";
import { useScrollTo, debounce } from "@pureadmin/utils";

const scrollRef = ref();
const { message } = useMessage();

// 加个防抖。连续点击,只会执行第一次点击事件,立即执行
const onLeft = debounce(
  () =>
    useScrollTo({
      el: scrollRef,
      to: 0,
      directions: "scrollLeft",
      duration: 2000,
      callback: msg => {
        msg === "滚动完毕"
          ? message.success("已滚动到最左侧")
          : message.info(msg);
      }
    }).start(),
  1200,
  true
);

const onRight = debounce(
  () =>
    useScrollTo({
      el: scrollRef,
      to: scrollRef.value!.scrollWidth,
      directions: "scrollLeft",
      duration: 2000,
      callback: msg => {
        msg === "滚动完毕"
          ? message.success("已滚动到最右侧")
          : message.info(msg);
      }
    }).start(),
  1200,
  true
);

const onLeftShortly = () => {
  useScrollTo({ el: scrollRef, to: 0, directions: "scrollLeft" }).start();
};

const onRightShortly = () => {
  useScrollTo({
    el: scrollRef,
    to: scrollRef.value!.scrollWidth,
    directions: "scrollLeft"
  }).start();
};
</script>

<template>
  <naive-theme>
    <div
      ref="scrollRef"
      class="w-full my-3 overflow-x-scroll flex border-solid border-1 border-[var(--vp-c-divider)] rounded-lg"
    >
      <div
        v-for="(_, index) in 50"
        :key="index"
        class="shrink-0 text-center px-[20px] pt-[28px]"
      >
        <img
          class="rounded-lg w-[80px]"
          :src="`https://xiaoxian521.github.io/hyperlink/avatar/400*400_${
            index + 1
          }.jpg`"
        />
        <p>{{ faker.person.firstName() }}</p>
      </div>
    </div>
    <n-button tertiary size="small" class="mt-2" @click="onLeft">
      滚动到最左侧
    </n-button>
    <n-button tertiary size="small" class="mt-2 ml-2" @click="onRight">
      滚动到最右侧
    </n-button>
    <br />
    <n-button tertiary size="small" class="mt-2" @click="onLeftShortly">
      滚动到最左侧(无缓动效果)
    </n-button>
    <n-button tertiary size="small" class="mt-2 ml-2" @click="onRightShortly">
      滚动到最右侧(无缓动效果)
    </n-button>
  </naive-theme>
</template>

最简代码

整页滚动到顶部

vue
<script setup lang="ts">
import { useScrollTo } from "@pureadmin/utils";

const onPageTop = () => {
  useScrollTo({
    el: document.documentElement,
    to: 0,
    directions: "scrollTop"
  }).start();
};
</script>

<template>
  <button @click="onPageTop">整页滚动到顶部</button>
</template>

API

参数

ts
//  在此处配置参数
const {} = useScrollTo(options);
参数属性必传说明类型
el滚动对象的实例Ref<Element>/HTMLElement
to滚动到某个位置number
directions滚动方向scrollTop/scrollLeft
duration滚动时长,单位毫秒。默认0,没有缓动效果number
callback滚动完毕的回调,返回一个参数msgmsg等于滚动完毕,代表滚动完成;msg等于无需滚动,代表当前已处于滚动目标位置,无需滚动(msg?:string) => void

返回值、方法

返回值、方法说明类型
start开始滚动() => void
stop暂停滚动() => void

Released under the MIT License