Skip to content

Commit

Permalink
feat(virtual-scroll): visibleSize property (#2164)
Browse files Browse the repository at this point in the history
  • Loading branch information
necoxrr authored Sep 25, 2024
1 parent f646fe7 commit e7635f8
Show file tree
Hide file tree
Showing 12 changed files with 134 additions and 55 deletions.
11 changes: 11 additions & 0 deletions examples/sites/demos/apis/virtual-scroll.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,17 @@ export default {
},
mode: ['pc'],
pcDemo: 'basic-usage'
},
{
name: 'visibleSize',
type: 'Number',
defaultValue: '400',
desc: {
'zh-CN': '显示区域的高度/宽度',
'en-US': 'Height/width of display area.'
},
mode: ['pc'],
pcDemo: 'basic-usage'
}
],
events: [],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
<template>
<div>
<!-- vue3 -->
<TinyVirtualScroll :data="showData" :itemSize="50" itemIndex="key" class="tiny-virtual-scroll" direction="vertical">
<TinyVirtualScroll
:data="showData"
:itemSize="50"
itemIndex="key"
class="tiny-virtual-scroll"
:visibleSize="300"
direction="vertical"
>
<template #default="props">
<div class="tiny-virtual-scroll-item">
{{ props.item.value }}
Expand Down Expand Up @@ -33,10 +40,6 @@ showData.value = Array.from(Array(1000), (v, k) => {
/* display: flex; */
}
.tiny-virtual-scroll {
height: 300px;
}
.tiny-virtual-scroll-item {
padding: 10px;
border-bottom: 2px solid #ddd;
Expand Down
6 changes: 3 additions & 3 deletions examples/sites/demos/pc/app/virtual-scroll/basic-usage.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div class="virtual-scroll-demo">
<!-- Vue2的选项式API -->
<TinyVirtualScroll :data="showData" :itemSize="50" itemIndex="key" class="tiny-virtual-scroll">
<TinyVirtualScroll :data="showData" :itemSize="50" itemIndex="key" :visibleSize="300" class="tiny-virtual-scroll">
<template #default="props">
<div class="tiny-virtual-scroll-item">
{{ props.item.value }}
Expand Down Expand Up @@ -42,9 +42,9 @@ export default {
/* display: flex; */
}
.tiny-virtual-scroll {
/* .tiny-virtual-scroll {
height: 300px;
}
} */
.tiny-virtual-scroll-item {
padding: 10px;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
<template>
<div class="virtual-scroll-demo">
<TinyVirtualScroll :data="showData" :estimatedItemSize="50" itemIndex="id" class="tiny-virtual-scroll"
direction="vertical" :buffer="0.5">
<TinyVirtualScroll
:data="showData"
:estimatedItemSize="50"
itemIndex="id"
:visibleSize="300"
class="tiny-virtual-scroll"
direction="vertical"
:buffer="0.5"
>
<template #default="props">
<div class="tiny-virtual-scroll-item">
{{ props.item.value }}
Expand Down Expand Up @@ -34,7 +41,6 @@ for (let i = 1; i <= 10000; i++) {
}
.tiny-virtual-scroll {
height: 300px;
width: 100%;
}
Expand Down
15 changes: 11 additions & 4 deletions examples/sites/demos/pc/app/virtual-scroll/dynamic-height.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
<template>
<div class="virtual-scroll-demo">
<!-- Vue2的选项式API -->
<TinyVirtualScroll :data="showData" :estimatedItemSize="50" itemIndex="id" class="tiny-virtual-scroll"
direction="vertical" :buffer="0.5">
<TinyVirtualScroll
:data="showData"
:estimatedItemSize="50"
itemIndex="id"
:visibleSize="300"
class="tiny-virtual-scroll"
direction="vertical"
:buffer="0.5"
>
<template #default="props">
<div class="tiny-virtual-scroll-item">
{{ props.item.value }}
Expand Down Expand Up @@ -41,9 +48,9 @@ export default {
/* width: 600px; */
}
.tiny-virtual-scroll {
/* .tiny-virtual-scroll {
height: 400px;
}
} */
.tiny-virtual-scroll-item {
padding: 10px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@
<tiny-button type="primary" plain @click="showScroll = !showScroll">切换可见性</tiny-button>
</div>
<div class="context" v-show="showScroll">
<TinyVirtualScroll ref="scroller" :data="showData" :itemSize="50" itemIndex="key" class="tiny-virtual-scroll"
direction="vertical">
<TinyVirtualScroll
ref="scroller"
:data="showData"
:itemSize="50"
itemIndex="key"
:visibleSize="400"
class="tiny-virtual-scroll"
direction="vertical"
>
<template #default="props">
<div class="tiny-virtual-scroll-item">
{{ props.item.value }}
Expand Down Expand Up @@ -50,10 +57,6 @@ showData.value = Array.from(Array(1000), (v, k) => {
text-align: center;
}
.scrollTo-demo .context .tiny-virtual-scroll {
height: 300px;
}
.scrollTo-demo .context .tiny-virtual-scroll .tiny-virtual-scroll-item {
padding: 10px;
border-bottom: 2px solid #ddd;
Expand Down
15 changes: 11 additions & 4 deletions examples/sites/demos/pc/app/virtual-scroll/show-status.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@
<tiny-button type="primary" plain @click="showScroll = !showScroll">切换可见性</tiny-button>
</div>
<div class="context" v-show="showScroll">
<TinyVirtualScroll ref="scroller" :data="showData" :itemSize="50" itemIndex="key" class="tiny-virtual-scroll"
direction="vertical">
<TinyVirtualScroll
ref="scroller"
:data="showData"
:itemSize="50"
itemIndex="key"
:visibleSize="400"
class="tiny-virtual-scroll"
direction="vertical"
>
<template #default="props">
<div class="tiny-virtual-scroll-item">
{{ props.item.value }}
Expand Down Expand Up @@ -61,9 +68,9 @@ export default {
text-align: center;
}
.scrollTo-demo .context .tiny-virtual-scroll {
/* .scrollTo-demo .context .tiny-virtual-scroll {
height: 300px;
}
} */
.scrollTo-demo .context .tiny-virtual-scroll .tiny-virtual-scroll-item {
padding: 10px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,15 @@
<tiny-input type="number" v-model.number="scrollto" :min="1" :max="showData.length"></tiny-input>
</div>
<div class="main">
<TinyVirtualScroll ref="scroller" :data="showData" :itemSize="50" itemIndex="key" class="tiny-virtual-scroll"
direction="vertical">
<TinyVirtualScroll
ref="scroller"
:data="showData"
:itemSize="50"
itemIndex="key"
:visibleSize="300"
class="tiny-virtual-scroll"
direction="vertical"
>
<template #default="props">
<div class="tiny-virtual-scroll-item">
{{ props.item.value }}
Expand Down Expand Up @@ -59,10 +66,6 @@ showData.value = Array.from(Array(1000), (v, k) => {
width: 250px;
}
.scrollTo-demo .main .tiny-virtual-scroll {
height: 300px;
}
.scrollTo-demo .main .tiny-virtual-scroll .tiny-virtual-scroll-item {
padding: 10px;
border-bottom: 2px solid #ddd;
Expand Down
15 changes: 9 additions & 6 deletions examples/sites/demos/pc/app/virtual-scroll/specified-item.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,15 @@
<tiny-input type="number" v-model.number="scrollto" :min="1" :max="showData.length"></tiny-input>
</div>
<div class="main">
<TinyVirtualScroll ref="scroller" :data="showData" :itemSize="50" itemIndex="key" class="tiny-virtual-scroll"
direction="vertical">
<TinyVirtualScroll
ref="scroller"
:data="showData"
:itemSize="50"
itemIndex="key"
:visibleSize="300"
class="tiny-virtual-scroll"
direction="vertical"
>
<template #default="props">
<div class="tiny-virtual-scroll-item">
{{ props.item.value }}
Expand Down Expand Up @@ -65,10 +72,6 @@ export default {
width: 250px;
}
.scrollTo-demo .main .tiny-virtual-scroll {
height: 300px;
}
.scrollTo-demo .main .tiny-virtual-scroll .tiny-virtual-scroll-item {
padding: 10px;
border-bottom: 2px solid #ddd;
Expand Down
6 changes: 5 additions & 1 deletion packages/renderless/src/virtual-scroll/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ export const handleScroll = ({ props, state, virtualScroll, nextTick, items, ...
if (!virtualScroll.value) return
await nextTick()
let start, end, totalSize, bufferSize
const size = props.direction === 'vertical' ? virtualScroll.value.clientHeight : virtualScroll.value.clientWidth
const size = props.visibleSize

const viewNum = Math.ceil(size / (props.itemSize ?? props.estimatedItemSize))

const scrollPosition =
props.direction === 'vertical' ? virtualScroll.value.scrollTop : virtualScroll.value.scrollLeft
if (state.temporary.prerender) {
Expand All @@ -85,7 +87,9 @@ export const handleScroll = ({ props, state, virtualScroll, nextTick, items, ...
viewStart + viewNum + bufferItems < state.data.length ? viewStart + viewNum + bufferItems : state.data.length

state.visibleData = state.data.slice(start, end)

state.translate = start * props.itemSize

return
}

Expand Down
5 changes: 5 additions & 0 deletions packages/vue/src/virtual-scroll/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ export default defineComponent({
// 预渲染条数
type: Number,
default: 0
},
visibleSize: {
type: Number,
default: 400,
require: true
}
},

Expand Down
61 changes: 44 additions & 17 deletions packages/vue/src/virtual-scroll/src/pc.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,39 @@
<template>
<div class="tiny-virtual-scroll" ref="virtualScroll" @scroll="handleScroll"
:style="direction === 'vertical' ? {} : { whiteSpace: 'nowrap' }">
<div class="virtual-scroll-context"
:style="direction === 'vertical' ? { 'height': `${state.totalSize}px` } : { 'width': `${state.totalSize}px` }">
</div>
<div class="virtual-scroll-wrapper" :style="direction === 'vertical'
? { 'transform': `translate3d(0,${state.translate}px,0)`, flexDirection: 'column' }
: {
'transform': `translate3d(${state.translate}px,0,0)`,
flexDirection: 'row',
display: 'flex'
// width: 'max-content'
}
">
<div
class="tiny-virtual-scroll"
ref="virtualScroll"
@scroll="handleScroll"
:style="
direction === 'vertical'
? { 'height': `${visibleSize}px` }
: { 'width': `${visibleSize}px`, whiteSpace: 'nowrap' }
"
>
<div
class="virtual-scroll-context"
:style="direction === 'vertical' ? { 'height': `${state.totalSize}px` } : { 'width': `${state.totalSize}px` }"
></div>
<div
class="virtual-scroll-wrapper"
:style="
direction === 'vertical'
? { 'transform': `translate3d(0,${state.translate}px,0)`, flexDirection: 'column' }
: {
'transform': `translate3d(${state.translate}px,0,0)`,
flexDirection: 'row',
display: 'flex'
// width: 'max-content'
}
"
>
<!-- 每项内容 -->
<div class="virtual-scroll-item" ref="items"
<div
class="virtual-scroll-item"
ref="items"
:style="direction === 'vertical' ? { 'height': `${itemSize}px` } : { 'width': `${itemSize}px ` }"
v-for="(item, index) in state.visibleData" :key="item[itemIndex] || index">
v-for="(item, index) in state.visibleData"
:key="item[itemIndex] || index"
>
<slot :item="item" />
</div>
</div>
Expand All @@ -28,7 +45,17 @@ import { renderless, api } from '@opentiny/vue-renderless/virtual-scroll/vue'
import { props, setup, defineComponent } from '@opentiny/vue-common'
export default defineComponent({
props: [...props, 'data', 'itemSize', 'itemIndex', 'direction', 'estimatedItemSize', 'buffer', 'prerender'],
props: [
...props,
'data',
'itemSize',
'itemIndex',
'direction',
'estimatedItemSize',
'buffer',
'prerender',
'visibleSize'
],
setup(props, context) {
return setup({ props, context, renderless, api })
}
Expand Down

0 comments on commit e7635f8

Please sign in to comment.