mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-01-24 02:00:25 +08:00
feat(VirtualScroll): 虚拟滚动增加滚动到顶部, 底部, 指定项方法 (#3687)
This commit is contained in:
parent
9882e8df86
commit
7c52f083db
@ -52,7 +52,7 @@
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'VirtualScroll',
|
name: 'VirtualScroll',
|
||||||
props,
|
props,
|
||||||
setup(props, { slots }) {
|
setup(props, { slots, expose }) {
|
||||||
const wrapElRef = ref<HTMLDivElement | null>(null);
|
const wrapElRef = ref<HTMLDivElement | null>(null);
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
first: 0,
|
first: 0,
|
||||||
@ -128,6 +128,31 @@
|
|||||||
state.last = getLast(state.first);
|
state.last = getLast(state.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function scrollToTop() {
|
||||||
|
const wrapEl = unref(wrapElRef);
|
||||||
|
if (!wrapEl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wrapEl.scrollTop = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function scrollToBottom() {
|
||||||
|
const wrapEl = unref(wrapElRef);
|
||||||
|
if (!wrapEl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wrapEl.scrollTop = wrapEl.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
function scrollToItem(index: number) {
|
||||||
|
const wrapEl = unref(wrapElRef);
|
||||||
|
if (!wrapEl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const i = index - 1 > 0 ? index - 1 : 0;
|
||||||
|
wrapEl.scrollTop = i * unref(getItemHeightRef);
|
||||||
|
}
|
||||||
|
|
||||||
function renderChildren() {
|
function renderChildren() {
|
||||||
const { items = [] } = props;
|
const { items = [] } = props;
|
||||||
return items.slice(unref(getFirstToRenderRef), unref(getLastToRenderRef)).map(genChild);
|
return items.slice(unref(getFirstToRenderRef), unref(getLastToRenderRef)).map(genChild);
|
||||||
@ -143,6 +168,13 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expose({
|
||||||
|
wrapElRef,
|
||||||
|
scrollToTop,
|
||||||
|
scrollToItem,
|
||||||
|
scrollToBottom,
|
||||||
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
state.last = getLast(0);
|
state.last = getLast(0);
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
|
@ -4,8 +4,7 @@
|
|||||||
.ant-input {
|
.ant-input {
|
||||||
&-number,
|
&-number,
|
||||||
&-number-group-wrapper {
|
&-number-group-wrapper {
|
||||||
width: 100% !important;
|
width: 100%;
|
||||||
min-width: 110px;
|
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<PageWrapper class="virtual-scroll-demo">
|
<PageWrapper class="virtual-scroll-demo">
|
||||||
<Divider>基础滚动示例</Divider>
|
<Divider>基础滚动示例</Divider>
|
||||||
|
<div class="text-center mb-4">
|
||||||
|
<a-button @click="vScrollRef?.scrollToTop()">滚动到顶部</a-button>
|
||||||
|
<a-button @click="vScrollRef?.scrollToBottom()" class="mx-2">滚动到底部</a-button>
|
||||||
|
<a-button @click="vScrollRef?.scrollToItem(scrollToItemIndex)"
|
||||||
|
>滚动到第
|
||||||
|
<input-number
|
||||||
|
v-model:value="scrollToItemIndex"
|
||||||
|
class="!w-60px mx-1"
|
||||||
|
:min="1"
|
||||||
|
:max="data.length"
|
||||||
|
:precision="0"
|
||||||
|
size="small"
|
||||||
|
:controls="false"
|
||||||
|
@keydown.enter="vScrollRef?.scrollToItem(scrollToItemIndex)"
|
||||||
|
/>
|
||||||
|
条
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
<div class="virtual-scroll-demo-wrap">
|
<div class="virtual-scroll-demo-wrap">
|
||||||
<VScroll :itemHeight="41" :items="data" :height="300" :width="300">
|
<VScroll :itemHeight="41" :items="data" :height="300" :width="300" ref="vScrollRef">
|
||||||
<template #default="{ item }">
|
<template #default="{ item }">
|
||||||
<div class="virtual-scroll-demo__item">
|
<div class="virtual-scroll-demo__item">
|
||||||
{{ item.title }}
|
{{ item.title }}
|
||||||
@ -24,9 +42,13 @@
|
|||||||
</PageWrapper>
|
</PageWrapper>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { VScroll } from '@/components/VirtualScroll';
|
|
||||||
import { Divider } from 'ant-design-vue';
|
|
||||||
import { PageWrapper } from '@/components/Page';
|
import { PageWrapper } from '@/components/Page';
|
||||||
|
import { VScroll } from '@/components/VirtualScroll';
|
||||||
|
import { Divider, InputNumber } from 'ant-design-vue';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
const vScrollRef = ref<typeof VScroll>();
|
||||||
|
const scrollToItemIndex = ref(1000);
|
||||||
|
|
||||||
const data = (() => {
|
const data = (() => {
|
||||||
const arr: any[] = [];
|
const arr: any[] = [];
|
||||||
|
Loading…
Reference in New Issue
Block a user