📄 useVirtualList¶
📊 Analysis Summary¶
| Metric | Count |
|---|---|
| 🔧 Functions | 12 |
| 📦 Imports | 10 |
| 📊 Variables & Constants | 3 |
| 🟢 Vue Composition API | 6 |
| 📐 Interfaces | 9 |
| 📑 Type Aliases | 7 |
📚 Table of Contents¶
🛠️ File Location:¶
📂 packages/core/useVirtualList/index.ts
📦 Imports¶
| Name | Source |
|---|---|
ComputedRef |
vue |
MaybeRef |
vue |
Ref |
vue |
ShallowRef |
vue |
StyleValue |
vue |
computed |
vue |
deepRef |
vue |
shallowRef |
vue |
watch |
vue |
useElementSize |
../useElementSize |
Variables & Constants¶
| Name | Type | Kind | Value | Exported |
|---|---|---|---|---|
scrollToDictionaryForElemen... |
{ readonly horizontal: "scrollLeft"; ... |
const | { horizontal: 'scrollLeft', vertical: 'scrollTop', } as const |
✗ |
scrollToDictionaryForElemen... |
{ readonly horizontal: "left"; readon... |
const | { horizontal: 'left', vertical: 'top', } as const |
✗ |
defaultScrollToOptions |
UseVirtualListScrollToOptions |
const | { behavior: 'auto', block: 'start', inline: 'nearest' } |
✗ |
Vue Composition API¶
| Name | Type | Reactive Variables | Composables |
|---|---|---|---|
watch |
watch | none | none |
computed |
computed | none | none |
computed |
computed | none | none |
computed |
computed | none | none |
computed |
computed | none | none |
computed |
computed | none | none |
Functions¶
useVirtualList(list: MaybeRef<readonly T[]>, options: UseVirtualListOptions): UseVirtualListReturn<T>¶
Please consider using vue-virtual-scroller if you are looking for more features.
Raw JSDoc
Calls:
useVerticalVirtualListuseHorizontalVirtualListcalculateRange
Code
export function useVirtualList<T = any>(list: MaybeRef<readonly T[]>, options: UseVirtualListOptions): UseVirtualListReturn<T> {
const { containerStyle, wrapperProps, scrollTo, calculateRange, currentList, containerRef } = 'itemHeight' in options
? useVerticalVirtualList(options, list)
: useHorizontalVirtualList(options, list)
return {
list: currentList,
scrollTo,
containerProps: {
ref: containerRef,
onScroll: () => {
calculateRange()
},
style: containerStyle,
},
wrapperProps,
}
}
useVirtualListResources(list: MaybeRef<readonly T[]>): UseVirtualListResources<T>¶
Parameters:
listMaybeRef<readonly T[]>
Returns: UseVirtualListResources<T>
Calls:
shallowRef (from vue)useElementSize (from ../useElementSize)deepRef (from vue)
Code
function useVirtualListResources<T>(list: MaybeRef<readonly T[]>): UseVirtualListResources<T> {
const containerRef = shallowRef<HTMLElement | null>(null)
const size = useElementSize(containerRef)
const currentList: Ref<UseVirtualListItem<T>[]> = deepRef([])
const source = shallowRef(list)
const state: Ref<{ start: number, end: number }> = deepRef({ start: 0, end: 10 })
return { state, source, currentList, size, containerRef }
}
createGetViewCapacity(state: UseVirtualListResources<T>['state'], source: UseVirtualListResources<T>['source'], itemSize: UseVirtualListItemSize): (containerSize: number) => number¶
Parameters:
stateUseVirtualListResources<T>['state']sourceUseVirtualListResources<T>['source']itemSizeUseVirtualListItemSize
Returns: (containerSize: number) => number
Calls:
Math.ceilitemSize
Code
function createGetViewCapacity<T>(state: UseVirtualListResources<T>['state'], source: UseVirtualListResources<T>['source'], itemSize: UseVirtualListItemSize) {
return (containerSize: number) => {
if (typeof itemSize === 'number')
return Math.ceil(containerSize / itemSize)
const { start = 0 } = state.value
let sum = 0
let capacity = 0
for (let i = start; i < source.value.length; i++) {
const size = itemSize(i)
sum += size
capacity = i
if (sum > containerSize)
break
}
return capacity - start
}
}
createGetOffset(source: UseVirtualListResources<T>['source'], itemSize: UseVirtualListItemSize): (scrollDirection: number) => number¶
Parameters:
sourceUseVirtualListResources<T>['source']itemSizeUseVirtualListItemSize
Returns: (scrollDirection: number) => number
Calls:
Math.flooritemSize
Code
function createGetOffset<T>(source: UseVirtualListResources<T>['source'], itemSize: UseVirtualListItemSize) {
return (scrollDirection: number) => {
if (typeof itemSize === 'number')
return Math.floor(scrollDirection / itemSize) + 1
let sum = 0
let offset = 0
for (let i = 0; i < source.value.length; i++) {
const size = itemSize(i)
sum += size
if (sum >= scrollDirection) {
offset = i
break
}
}
return offset + 1
}
}
createCalculateRange(…): () => void¶
Parameters:
type'horizontal' | 'vertical'overscannumbergetOffsetReturnType<typeof createGetOffset>getViewCapacityReturnType<typeof createGetViewCapacity>{ containerRef, state, currentList, source }UseVirtualListResources<T>
Returns: () => void
Calls:
getOffsetgetViewCapacitysource.value .slice(state.value.start, state.value.end) .map
Code
function createCalculateRange<T>(
type: 'horizontal' | 'vertical',
overscan: number,
getOffset: ReturnType<typeof createGetOffset>,
getViewCapacity: ReturnType<typeof createGetViewCapacity>,
{ containerRef, state, currentList, source }: UseVirtualListResources<T>,
) {
return () => {
const element = containerRef.value
if (element) {
const offset = getOffset(type === 'vertical' ? element.scrollTop : element.scrollLeft)
const viewCapacity = getViewCapacity(type === 'vertical' ? element.clientHeight : element.clientWidth)
const from = offset - overscan
const to = offset + viewCapacity + overscan
state.value = {
start: from < 0 ? 0 : from,
end: to > source.value.length
? source.value.length
: to,
}
currentList.value = source.value
.slice(state.value.start, state.value.end)
.map((ele, index) => ({
data: ele,
index: index + state.value.start,
}))
}
}
}
createGetDistance(itemSize: UseVirtualListItemSize, source: UseVirtualListResources<T>['source']): (index: number) => any¶
Parameters:
itemSizeUseVirtualListItemSizesourceUseVirtualListResources<T>['source']
Returns: (index: number) => any
Calls:
source.value .slice(0, index) .reduceitemSize
Code
function createGetDistance<T>(itemSize: UseVirtualListItemSize, source: UseVirtualListResources<T>['source']) {
return (index: number) => {
if (typeof itemSize === 'number') {
const size = index * itemSize
return size
}
const size = source.value
.slice(0, index)
.reduce((sum, _, i) => sum + itemSize(i), 0)
return size
}
}
useWatchForSizes(size: UseVirtualElementSizes, listRef: Ref<readonly T[]>, totalSize: ComputedRef<number>, containerRef: Ref<HTMLElement | null>, calculateRange: () => void): void¶
Parameters:
sizeUseVirtualElementSizeslistRefRef<readonly T[]>totalSizeComputedRef<number>containerRefRef<HTMLElement | null>calculateRange() => void
Returns: void
Calls:
watch (from vue)calculateRange
Code
createComputedTotalSize(itemSize: UseVirtualListItemSize, source: UseVirtualListResources<T>['source']): any¶
Parameters:
itemSizeUseVirtualListItemSizesourceUseVirtualListResources<T>['source']
Returns: any
Calls:
computed (from vue)source.value.reduceitemSize
Code
createScrollTo(…): (index: number, options?: UseVirtualListScrollToOptions) =>…¶
Parameters:
type'horizontal' | 'vertical'calculateRange() => voidgetDistanceReturnType<typeof createGetDistance>containerRefUseVirtualListResources<T>['containerRef']itemSizeUseVirtualListItemSize
Returns: (index: number, options?: UseVirtualListScrollToOptions) => void
Calls:
itemSizegetDistancecontainerRef.value.scrollTocalculateRange
Code
function createScrollTo<T>(
type: 'horizontal' | 'vertical',
calculateRange: () => void,
getDistance: ReturnType<typeof createGetDistance>,
containerRef: UseVirtualListResources<T>['containerRef'],
itemSize: UseVirtualListItemSize,
) {
return (index: number, options: UseVirtualListScrollToOptions = defaultScrollToOptions) => {
if (!containerRef.value)
return
options = { ...defaultScrollToOptions, ...options }
let offset = 0
const axisToCheck = options[type === 'horizontal' ? 'inline' : 'block']
if (axisToCheck) {
const containerSize = type === 'horizontal' ? containerRef.value.clientWidth : containerRef.value.clientHeight
const fullItemSize = typeof itemSize === 'number' ? itemSize : itemSize(index)
if (axisToCheck === 'center') {
offset = (containerSize / 2) - (fullItemSize / 2)
}
else if (axisToCheck === 'end') {
offset = containerSize - fullItemSize
}
else if (axisToCheck === 'nearest') {
const containerScrollPosition = containerRef.value[scrollToDictionaryForElementScrollKey[type]]
if (getDistance(index) > containerScrollPosition + (containerSize / 2)) {
offset = containerSize - fullItemSize
}
}
}
containerRef.value.scrollTo({
[scrollToDictionaryForElementScrollToKey[type]]: getDistance(index) - offset,
behavior: options.behavior,
})
calculateRange()
}
}
useHorizontalVirtualList(options: UseHorizontalVirtualListOptions, list: MaybeRef<readonly T[]>): { scrollTo: (index: number, options?: UseVirtualListScrollT…¶
Parameters:
optionsUseHorizontalVirtualListOptionslistMaybeRef<readonly T[]>
Returns: { scrollTo: (index: number, options?: UseVirtualListScrollToOptions) => void; calculateRange: () => void; wrapperProps: any; containerStyle: StyleValue; currentList: Ref<UseVirtualListArray<T>>; containerRef: Ref<HTMLElement>; }
Calls:
useVirtualListResourcescreateGetViewCapacitycreateGetOffsetcreateCalculateRangecreateGetDistancecomputed (from vue)getDistanceLeftcreateComputedTotalSizeuseWatchForSizescreateScrollTo
Code
function useHorizontalVirtualList<T>(options: UseHorizontalVirtualListOptions, list: MaybeRef<readonly T[]>) {
const resources = useVirtualListResources(list)
const { state, source, currentList, size, containerRef } = resources
const containerStyle: StyleValue = { overflowX: 'auto' }
const { itemWidth, overscan = 5 } = options
const getViewCapacity = createGetViewCapacity(state, source, itemWidth)
const getOffset = createGetOffset(source, itemWidth)
const calculateRange = createCalculateRange('horizontal', overscan, getOffset, getViewCapacity, resources)
const getDistanceLeft = createGetDistance(itemWidth, source)
const offsetLeft = computed(() => getDistanceLeft(state.value.start))
const totalWidth = createComputedTotalSize(itemWidth, source)
useWatchForSizes(size, source, totalWidth, containerRef, calculateRange)
const scrollTo = createScrollTo('horizontal', calculateRange, getDistanceLeft, containerRef, itemWidth)
const wrapperProps = computed(() => {
return {
style: {
height: '100%',
width: `${totalWidth.value - offsetLeft.value}px`,
marginLeft: `${offsetLeft.value}px`,
display: 'flex',
},
}
})
return {
scrollTo,
calculateRange,
wrapperProps,
containerStyle,
currentList,
containerRef,
}
}
useVerticalVirtualList(options: UseVerticalVirtualListOptions, list: MaybeRef<readonly T[]>): { calculateRange: () => void; scrollTo: (index: number, opt…¶
Parameters:
optionsUseVerticalVirtualListOptionslistMaybeRef<readonly T[]>
Returns: { calculateRange: () => void; scrollTo: (index: number, options?: UseVirtualListScrollToOptions) => void; containerStyle: StyleValue; wrapperProps: any; currentList: Ref<UseVirtualListArray<T>>; containerRef: Ref<HTMLElement>; }
Calls:
useVirtualListResourcescreateGetViewCapacitycreateGetOffsetcreateCalculateRangecreateGetDistancecomputed (from vue)getDistanceTopcreateComputedTotalSizeuseWatchForSizescreateScrollTo
Code
function useVerticalVirtualList<T>(options: UseVerticalVirtualListOptions, list: MaybeRef<readonly T[]>) {
const resources = useVirtualListResources(list)
const { state, source, currentList, size, containerRef } = resources
const containerStyle: StyleValue = { overflowY: 'auto' }
const { itemHeight, overscan = 5 } = options
const getViewCapacity = createGetViewCapacity(state, source, itemHeight)
const getOffset = createGetOffset(source, itemHeight)
const calculateRange = createCalculateRange('vertical', overscan, getOffset, getViewCapacity, resources)
const getDistanceTop = createGetDistance(itemHeight, source)
const offsetTop = computed(() => getDistanceTop(state.value.start))
const totalHeight = createComputedTotalSize(itemHeight, source)
useWatchForSizes(size, source, totalHeight, containerRef, calculateRange)
const scrollTo = createScrollTo('vertical', calculateRange, getDistanceTop, containerRef, itemHeight)
const wrapperProps = computed(() => {
return {
style: {
width: '100%',
height: `${totalHeight.value - offsetTop.value}px`,
marginTop: `${offsetTop.value}px`,
},
}
})
return {
calculateRange,
scrollTo,
containerStyle,
wrapperProps,
currentList,
containerRef,
}
}
Internal helpers¶
Declared inside another function in this file.
onScroll(): void¶
Returns: void
Calls:
calculateRange
Interfaces¶
UseHorizontalVirtualListOptions¶
Interface Code
Properties¶
| Name | Type | Optional | Description |
|---|---|---|---|
itemWidth |
UseVirtualListItemSize |
✗ | not shown |
UseVerticalVirtualListOptions¶
Interface Code
Properties¶
| Name | Type | Optional | Description |
|---|---|---|---|
itemHeight |
UseVirtualListItemSize |
✗ | not shown |
UseVirtualListOptionsBase¶
Interface Code
Properties¶
| Name | Type | Optional | Description |
|---|---|---|---|
overscan |
number |
✓ | not shown |
UseVirtualListItem<T>¶
Properties¶
| Name | Type | Optional | Description |
|---|---|---|---|
data |
T |
✗ | not shown |
index |
number |
✗ | not shown |
UseVirtualListScrollToOptions¶
Interface Code
Properties¶
| Name | Type | Optional | Description |
|---|---|---|---|
behavior |
ScrollBehavior |
✓ | not shown |
block |
ScrollLogicalPosition |
✓ | not shown |
inline |
ScrollLogicalPosition |
✓ | not shown |
UseVirtualListReturn<T>¶
Interface Code
export interface UseVirtualListReturn<T> {
list: Ref<UseVirtualListItem<T>[]>
scrollTo: (index: number, options?: UseVirtualListScrollToOptions) => void
containerProps: {
ref: Ref<HTMLElement | null>
onScroll: () => void
style: StyleValue
}
wrapperProps: ComputedRef<{
style: {
width: string
height: string
marginTop: string
} | {
width: string
height: string
marginLeft: string
display: string
}
}>
}
Properties¶
| Name | Type | Optional | Description |
|---|---|---|---|
list |
Ref<UseVirtualListItem<T>[]> |
✗ | not shown |
scrollTo |
(index: number, options?: UseVirtualListScrollToOptions) => void |
✗ | not shown |
containerProps |
{ ref: Ref<HTMLElement \| null> onScroll: () => void style: StyleValue } |
✗ | not shown |
wrapperProps |
ComputedRef<{ style: { width: string height: string marginTop: string } \| { ... |
✗ | not shown |
UseVirtualElementSizes¶
Properties¶
| Name | Type | Optional | Description |
|---|---|---|---|
width |
Ref<number> |
✗ | not shown |
height |
Ref<number> |
✗ | not shown |
UseVirtualListState¶
Properties¶
| Name | Type | Optional | Description |
|---|---|---|---|
start |
number |
✗ | not shown |
end |
number |
✗ | not shown |
UseVirtualListResources<T>¶
Interface Code
Properties¶
| Name | Type | Optional | Description |
|---|---|---|---|
state |
RefState |
✗ | not shown |
source |
UseVirtualListSource<T> |
✗ | not shown |
currentList |
UseVirtualListRefArray<T> |
✗ | not shown |
size |
UseVirtualElementSizes |
✗ | not shown |
containerRef |
UseVirtualListContainerRef |
✗ | not shown |
Type Aliases¶
UseVirtualListItemSize¶
UseVirtualListOptions¶
UseVirtualListContainerRef¶
UseVirtualListArray<T>¶
UseVirtualListRefArray<T>¶
UseVirtualListSource<T>¶
RefState¶
Generated by Syntax Scribe