Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions components/virtual-scroller/virtual-scroller.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,17 +123,20 @@ export default defineComponent({
virtualRef.value?.scrollBy(offset);
},
getItemOffset: (index: number) => {
virtualRef.value?.getItemOffset(index);
return virtualRef.value?.getItemOffset(index);
},
getItemSize: (index: number) => {
virtualRef.value?.getItemSize(index);
return virtualRef.value?.getItemSize(index);
},
findStartIndex: () => {
virtualRef.value?.findStartIndex();
},
findEndIndex: () => {
virtualRef.value?.findEndIndex();
},
getOffset,
getScrollSize,
getClientSize,
});

const onScroll = (e: Event) => {
Expand Down
10 changes: 4 additions & 6 deletions docs/.vitepress/components/virtualList/common.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<template>
<FVirtualScroller
<FVirtualList
ref="virtualList"
class="virtual-scroll-list-vertical"
dataKey="id"
:dataSources="dataItems"
:itemSize="100"
:scrollbarProps="{ height: 400 }"
:estimateSize="80"
:height="height"
>
<template #default="{ source, index }">
<div :data-index="index" class="item-inner">
Expand All @@ -16,7 +16,7 @@
<div class="desc">{{ source.desc }}</div>
</div>
</template>
</FVirtualScroller>
</FVirtualList>
<FButton style="margin-top: 10px;" @click="addMessage">添加消息{{ dataItems.length }}</FButton>
</template>

Expand Down Expand Up @@ -76,8 +76,6 @@ export default {
</script>

<style scoped>
.virtual-scroll-list-vertical .item-inner {
}
.virtual-scroll-list-vertical .item-inner .head {
font-weight: 500;
}
Expand Down
14 changes: 7 additions & 7 deletions docs/.vitepress/components/virtualList/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,10 @@ app.use(FVirtualList);

## 代码演示

### virtual-scroller

:::demo
common.vue
:::

### 不规则纵向滚动列表

:::demo
vertical.vue
common.vue
:::

### 不规则横向滚动列表
Expand All @@ -36,6 +30,12 @@ horizontal.vue
maxHeight.vue
:::

### 无限滚动

:::demo
infinite.vue
:::

### 滚动操作

:::demo
Expand Down
97 changes: 97 additions & 0 deletions docs/.vitepress/components/virtualList/infinite.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<template>
<FVirtualList
ref="virtualList"
class="virtual-scroll-list-vertical"
dataKey="id"
:dataSources="dataItems"
:estimateSize="80"
:height="height"
@toTop="handleToTop"
@toBottom="handleToBottom"
>
<template #default="{ source, index }">
<div :data-index="index" class="item-inner">
<div class="head">
<span># {{ source.index }}</span>
<span>{{ source.name }}</span>
</div>
<div class="desc">{{ source.desc }}</div>
</div>
</template>
</FVirtualList>
</template>

<script>
import { ref } from 'vue';

export default {
name: 'Vertical',
setup() {
const virtualList = ref(null);
const height = ref(400);
const sentence3 = [
'BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。',
'IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)',
'margin 重合,margin 塌陷',
'html5IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)',
];
const genUniqueId = (prefix) => {
return `${prefix}$${Math.random().toString(16).substr(9)}`;
};
const getSentences = () => {
const index = Math.floor(Math.random() * (sentence3.length - 1));
return sentence3[index];
};
const TOTAL_COUNT = 1000;
const dataItems = ref([]);

const createData = (length, startIndex, isAdd = true) => {
const result = [];
let count = length;
while (count--) {
const index = isAdd ? startIndex + length - count - 1 : startIndex - count - 1;
result.push({
index,
name: `${Math.random()}`,
id: genUniqueId(index),
desc: getSentences(),
});
}
return result;
};

dataItems.value = createData(TOTAL_COUNT, 1);

const handleToBottom = () => {
dataItems.value = [...dataItems.value, ...createData(10, dataItems.value[dataItems.value.length - 1].index + 1)];
};
const handleToTop = () => {
dataItems.value = [...createData(10, dataItems.value[0].index, false), ...dataItems.value];
setTimeout(() => {
virtualList.value.scrollToIndex(10);
}, 0);
};
return {
virtualList,
dataItems,
height,
handleToBottom,
handleToTop,
};
},
};
</script>

<style scoped>
.virtual-scroll-list-vertical .item-inner .head {
font-weight: 500;
}
.virtual-scroll-list-vertical .item-inner .head span:first-child {
margin-right: 1em;
}
.virtual-scroll-list-vertical .item-inner .desc {
margin-top: 0.5em;
margin-bottom: 1em;
text-align: justify;
}
</style>
41 changes: 33 additions & 8 deletions docs/.vitepress/components/virtualList/maxHeight.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@
<FVirtualList
class="virtual-scroll-list-max-height"
wrapClass="virtual-scroll-list-wrap"
:dataKey="(data) => data"
dataKey="id"
:dataSources="vals"
:estimateSize="80"
:height="height"
:maxHeight="maxHeight"
>
<template #default="{ source }">
<div class="virtual-scroll-item">
{{ source }}
{{ source.desc }}
</div>
</template>
</FVirtualList>
Expand All @@ -57,9 +57,36 @@ export default {
const maxHeight = ref(200);

const vals = ref([]);
for (let i = 0; i < 6; ++i) {
vals.value.push(i);
}
const sentence3 = [
'BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。',
'IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)',
'margin 重合,margin 塌陷',
'html5IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)IFC(Inline Formatting Contexts)直译为”内联格式化上下文”,IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)',
];
const genUniqueId = (prefix) => {
return `${prefix}$${Math.random().toString(16).substr(9)}`;
};
const getSentences = () => {
const index = Math.floor(Math.random() * (sentence3.length - 1));
return sentence3[index];
};

const createData = (length, startIndex, isAdd = true) => {
const result = [];
let count = length;
while (count--) {
const index = isAdd ? startIndex + length - count - 1 : startIndex - count - 1;
result.push({
index,
name: `${Math.random()}`,
id: genUniqueId(index),
desc: getSentences(),
});
}
return result;
};

vals.value = createData(1000, 1);

watch(
heightType,
Expand Down Expand Up @@ -97,9 +124,7 @@ export default {
width: 1000px;
}
.virtual-scroll-list-max-height .virtual-scroll-list-wrap .virtual-scroll-item {
height: 36px;
background: rgba(83, 132, 255, 0.06);
border-bottom: 2px solid #fff;
margin: 0.5em;
}
.virtual-scroll-list-max-height
.virtual-scroll-list-wrap
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
<template>
<FVirtualList
<FVirtualScroller
ref="virtualList"
class="virtual-scroll-list-vertical"
dataKey="id"
:dataSources="dataItems"
:estimateSize="80"
:itemSize="80"
:height="height"
>
<template #default="{ source, index }">
Expand All @@ -16,7 +15,7 @@
<div class="desc">{{ source.desc }}</div>
</div>
</template>
</FVirtualList>
</FVirtualScroller>
<FButton style="margin-top: 10px;" @click="addMessage">添加消息{{ dataItems.length }}</FButton>
</template>

Expand Down
69 changes: 69 additions & 0 deletions docs/.vitepress/components/virtualScroller/horizontal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<template>
<FVirtualScroller
class="virtual-scroll-list-horizontal"
:dataSources="items"
:itemSize="110"
direction="horizontal"
>
<template #default="{ source }">
<div
class="item-inner-horizontal"
:style="{ width: `${source.size}px` }"
>
<div class="index"># {{ source.index }}</div>
<div class="size">{{ source.size }}</div>
</div>
</template>
</FVirtualScroller>
</template>

<script>
const TOTAL_COUNT = 100;
const sizes = [60, 80, 100, 150, 180];

const genUniqueId = (prefix) => {
return `${prefix}$${Math.random().toString(16).substr(9)}`;
};

const dataItems = [];
let count = TOTAL_COUNT;
while (count--) {
const index = TOTAL_COUNT - count;
dataItems.push({
index,
id: genUniqueId(index),
size: sizes[Math.floor(Math.random() * 5)],
});
}

export default {
name: 'Horizontal',
setup() {
return {
items: dataItems,
};
},
};
</script>

<style scoped>
.virtual-scroll-list-horizontal {
width: 100%;
height: 120px;
}
.virtual-scroll-list-horizontal .item-inner-horizontal {
display: flex;
align-items: center;
flex-direction: column;
padding: 2em 0;
}
.virtual-scroll-list-horizontal .item-inner-horizontal .index {
width: 100%;
text-align: center;
}
.virtual-scroll-list-horizontal .item-inner-horizontal .size {
text-align: right;
color: darkgray;
font-size: 16px;
}
</style>
Loading