苗大
2 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with
59 additions and
6 deletions
-
src/components/VirtualScroll/src/VirtualScroll.vue
-
src/design/ant/input.less
-
src/views/demo/comp/scroll/VirtualScroll.vue
|
|
|
@ -52,7 +52,7 @@ |
|
|
|
export default defineComponent({ |
|
|
|
name: 'VirtualScroll', |
|
|
|
props, |
|
|
|
setup(props, { slots }) { |
|
|
|
setup(props, { slots, expose }) { |
|
|
|
const wrapElRef = ref<HTMLDivElement | null>(null); |
|
|
|
const state = reactive({ |
|
|
|
first: 0, |
|
|
|
@ -128,6 +128,31 @@ |
|
|
|
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() { |
|
|
|
const { items = [] } = props; |
|
|
|
return items.slice(unref(getFirstToRenderRef), unref(getLastToRenderRef)).map(genChild); |
|
|
|
@ -143,6 +168,13 @@ |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
expose({ |
|
|
|
wrapElRef, |
|
|
|
scrollToTop, |
|
|
|
scrollToItem, |
|
|
|
scrollToBottom, |
|
|
|
}); |
|
|
|
|
|
|
|
onMounted(() => { |
|
|
|
state.last = getLast(0); |
|
|
|
nextTick(() => { |
|
|
|
|
|
|
|
@ -4,8 +4,7 @@ |
|
|
|
.ant-input { |
|
|
|
&-number, |
|
|
|
&-number-group-wrapper { |
|
|
|
width: 100% !important; |
|
|
|
min-width: 110px; |
|
|
|
width: 100%; |
|
|
|
max-width: 100%; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -1,8 +1,26 @@ |
|
|
|
<template> |
|
|
|
<PageWrapper class="virtual-scroll-demo"> |
|
|
|
<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"> |
|
|
|
<VScroll :itemHeight="41" :items="data" :height="300" :width="300"> |
|
|
|
<VScroll :itemHeight="41" :items="data" :height="300" :width="300" ref="vScrollRef"> |
|
|
|
<template #default="{ item }"> |
|
|
|
<div class="virtual-scroll-demo__item"> |
|
|
|
{{ item.title }} |
|
|
|
@ -24,9 +42,13 @@ |
|
|
|
</PageWrapper> |
|
|
|
</template> |
|
|
|
<script lang="ts" setup> |
|
|
|
import { VScroll } from '@/components/VirtualScroll'; |
|
|
|
import { Divider } from 'ant-design-vue'; |
|
|
|
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 arr: any[] = []; |
|
|
|
|