mirror of
https://gitee.com/spark-store-project/spark-store
synced 2026-04-26 09:20:18 +08:00
feat(组件): 添加虚拟滚动优化应用网格性能
为AppGrid组件添加vue-virtual-scroller实现虚拟滚动功能,当应用数量超过50个时自动启用 更新package.json添加vue-virtual-scroller依赖 添加vue-virtual-scroller的类型声明 优化网格布局响应式处理,根据窗口宽度动态调整列数
This commit is contained in:
73
package-lock.json
generated
73
package-lock.json
generated
@@ -1,18 +1,19 @@
|
||||
{
|
||||
"name": "spark-store",
|
||||
"version": "4.9.9alpha4",
|
||||
"version": "5.0.0beta1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "spark-store",
|
||||
"version": "4.9.9alpha4",
|
||||
"version": "5.0.0beta1",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@tailwindcss/vite": "^4.1.18",
|
||||
"axios": "^1.13.2",
|
||||
"pino": "^10.3.0",
|
||||
"tailwindcss": "^4.1.18"
|
||||
"tailwindcss": "^4.1.18",
|
||||
"vue-virtual-scroller": "^2.0.0-beta.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@dotenvx/dotenvx": "^1.51.4",
|
||||
@@ -114,7 +115,6 @@
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
|
||||
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
@@ -123,7 +123,6 @@
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
|
||||
"integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
@@ -132,7 +131,6 @@
|
||||
"version": "7.29.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz",
|
||||
"integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.29.0"
|
||||
},
|
||||
@@ -156,7 +154,6 @@
|
||||
"version": "7.29.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
|
||||
"integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.27.1",
|
||||
"@babel/helper-validator-identifier": "^7.28.5"
|
||||
@@ -3089,7 +3086,6 @@
|
||||
"version": "3.5.30",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.30.tgz",
|
||||
"integrity": "sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.29.0",
|
||||
"@vue/shared": "3.5.30",
|
||||
@@ -3102,7 +3098,6 @@
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
|
||||
"integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
@@ -3113,14 +3108,12 @@
|
||||
"node_modules/@vue/compiler-core/node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
|
||||
},
|
||||
"node_modules/@vue/compiler-dom": {
|
||||
"version": "3.5.30",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.30.tgz",
|
||||
"integrity": "sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-core": "3.5.30",
|
||||
"@vue/shared": "3.5.30"
|
||||
@@ -3130,7 +3123,6 @@
|
||||
"version": "3.5.30",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.30.tgz",
|
||||
"integrity": "sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.29.0",
|
||||
"@vue/compiler-core": "3.5.30",
|
||||
@@ -3146,14 +3138,12 @@
|
||||
"node_modules/@vue/compiler-sfc/node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
|
||||
},
|
||||
"node_modules/@vue/compiler-ssr": {
|
||||
"version": "3.5.30",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.30.tgz",
|
||||
"integrity": "sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.5.30",
|
||||
"@vue/shared": "3.5.30"
|
||||
@@ -3178,7 +3168,6 @@
|
||||
"version": "3.5.30",
|
||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.30.tgz",
|
||||
"integrity": "sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/shared": "3.5.30"
|
||||
}
|
||||
@@ -3187,7 +3176,6 @@
|
||||
"version": "3.5.30",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.30.tgz",
|
||||
"integrity": "sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/reactivity": "3.5.30",
|
||||
"@vue/shared": "3.5.30"
|
||||
@@ -3197,7 +3185,6 @@
|
||||
"version": "3.5.30",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.30.tgz",
|
||||
"integrity": "sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/reactivity": "3.5.30",
|
||||
"@vue/runtime-core": "3.5.30",
|
||||
@@ -3209,7 +3196,6 @@
|
||||
"version": "3.5.30",
|
||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.30.tgz",
|
||||
"integrity": "sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-ssr": "3.5.30",
|
||||
"@vue/shared": "3.5.30"
|
||||
@@ -3221,8 +3207,7 @@
|
||||
"node_modules/@vue/shared": {
|
||||
"version": "3.5.30",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.30.tgz",
|
||||
"integrity": "sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ=="
|
||||
},
|
||||
"node_modules/@vue/test-utils": {
|
||||
"version": "2.4.6",
|
||||
@@ -4442,8 +4427,7 @@
|
||||
"node_modules/csstype": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
|
||||
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="
|
||||
},
|
||||
"node_modules/data-urls": {
|
||||
"version": "5.0.0",
|
||||
@@ -7961,6 +7945,12 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/mitt": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mitt/-/mitt-2.1.0.tgz",
|
||||
"integrity": "sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/mkdirp": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||
@@ -10073,7 +10063,7 @@
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"dev": true,
|
||||
"devOptional": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@@ -11514,7 +11504,6 @@
|
||||
"version": "3.5.30",
|
||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.30.tgz",
|
||||
"integrity": "sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.5.30",
|
||||
"@vue/compiler-sfc": "3.5.30",
|
||||
@@ -11561,6 +11550,24 @@
|
||||
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-observe-visibility": {
|
||||
"version": "2.0.0-alpha.1",
|
||||
"resolved": "https://registry.npmjs.org/vue-observe-visibility/-/vue-observe-visibility-2.0.0-alpha.1.tgz",
|
||||
"integrity": "sha512-flFbp/gs9pZniXR6fans8smv1kDScJ8RS7rEpMjhVabiKeq7Qz3D9+eGsypncjfIyyU84saU88XZ0zjbD6Gq/g==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"vue": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-resize": {
|
||||
"version": "2.0.0-alpha.1",
|
||||
"resolved": "https://registry.npmjs.org/vue-resize/-/vue-resize-2.0.0-alpha.1.tgz",
|
||||
"integrity": "sha512-7+iqOueLU7uc9NrMfrzbG8hwMqchfVfSzpVlCMeJQe4pyibqyoifDNbKTZvwxZKDvGkB+PdFeKvnGZMoEb8esg==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"vue": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-tsc": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-3.2.5.tgz",
|
||||
@@ -11577,6 +11584,20 @@
|
||||
"typescript": ">=5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-virtual-scroller": {
|
||||
"version": "2.0.0-beta.8",
|
||||
"resolved": "https://registry.npmjs.org/vue-virtual-scroller/-/vue-virtual-scroller-2.0.0-beta.8.tgz",
|
||||
"integrity": "sha512-b8/f5NQ5nIEBRTNi6GcPItE4s7kxNHw2AIHLtDp+2QvqdTjVN0FgONwX9cr53jWRgnu+HRLPaWDOR2JPI5MTfQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mitt": "^2.1.0",
|
||||
"vue-observe-visibility": "^2.0.0-alpha.1",
|
||||
"vue-resize": "^2.0.0-alpha.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/w3c-xmlserializer": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
"@tailwindcss/vite": "^4.1.18",
|
||||
"axios": "^1.13.2",
|
||||
"pino": "^10.3.0",
|
||||
"tailwindcss": "^4.1.18"
|
||||
"tailwindcss": "^4.1.18",
|
||||
"vue-virtual-scroller": "^2.0.0-beta.8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
试试其他关键词,或检查拼写是否正确
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 应用数量较少时,使用普通网格 -->
|
||||
<div
|
||||
v-else-if="!loading"
|
||||
v-else-if="!loading && apps.length <= 50"
|
||||
class="grid gap-4 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4"
|
||||
>
|
||||
<AppCard
|
||||
@@ -28,6 +30,28 @@
|
||||
@open-detail="$emit('open-detail', app)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 应用数量较多时,使用虚拟滚动 -->
|
||||
<RecycleScroller
|
||||
v-else-if="!loading"
|
||||
class="scroller"
|
||||
:items="gridRows"
|
||||
:item-size="itemHeight"
|
||||
key-field="id"
|
||||
v-slot="{ item }"
|
||||
>
|
||||
<div class="grid-row grid gap-x-4 gap-y-8" :class="gridColumnsClass">
|
||||
<AppCard
|
||||
v-for="app in item.apps"
|
||||
:key="app.pkgname"
|
||||
:app="app"
|
||||
:show-origin="storeFilter === 'both'"
|
||||
@open-detail="$emit('open-detail', app)"
|
||||
/>
|
||||
</div>
|
||||
</RecycleScroller>
|
||||
|
||||
<!-- 加载骨架屏 -->
|
||||
<div v-else class="grid gap-4 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4">
|
||||
<div
|
||||
v-for="n in 8"
|
||||
@@ -53,10 +77,13 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, onMounted, onUnmounted } from "vue";
|
||||
import { RecycleScroller } from "vue-virtual-scroller";
|
||||
import "vue-virtual-scroller/dist/vue-virtual-scroller.css";
|
||||
import AppCard from "./AppCard.vue";
|
||||
import type { App } from "../global/typedefinition";
|
||||
|
||||
defineProps<{
|
||||
const props = defineProps<{
|
||||
apps: App[];
|
||||
loading: boolean;
|
||||
storeFilter?: "spark" | "apm" | "both";
|
||||
@@ -65,4 +92,95 @@ defineProps<{
|
||||
defineEmits<{
|
||||
(e: "open-detail", app: App): void;
|
||||
}>();
|
||||
|
||||
// 当前列数
|
||||
const columns = ref(4);
|
||||
|
||||
// 根据窗口宽度更新列数
|
||||
const updateColumns = () => {
|
||||
const width = window.innerWidth;
|
||||
if (width >= 1536) columns.value = 4;
|
||||
else if (width >= 1280) columns.value = 3;
|
||||
else if (width >= 640) columns.value = 2;
|
||||
else columns.value = 1;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
updateColumns();
|
||||
window.addEventListener("resize", updateColumns);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener("resize", updateColumns);
|
||||
});
|
||||
|
||||
// 网格列数类名
|
||||
const gridColumnsClass = computed(() => {
|
||||
const map: Record<number, string> = {
|
||||
1: "grid-cols-1",
|
||||
2: "grid-cols-2",
|
||||
3: "grid-cols-3",
|
||||
4: "grid-cols-4",
|
||||
};
|
||||
return map[columns.value] || "grid-cols-4";
|
||||
});
|
||||
|
||||
// 每个应用卡片的高度(包括 gap)
|
||||
// 卡片实际高度约 96px + 垂直间距 32px (gap-y-8)
|
||||
const itemHeight = 128;
|
||||
|
||||
// 将应用列表分组为行
|
||||
const gridRows = computed(() => {
|
||||
const rows: { id: number; apps: App[] }[] = [];
|
||||
|
||||
for (let i = 0; i < props.apps.length; i += columns.value) {
|
||||
rows.push({
|
||||
id: i,
|
||||
apps: props.apps.slice(i, i + columns.value),
|
||||
});
|
||||
}
|
||||
|
||||
return rows;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.scroller {
|
||||
height: calc(100vh - 140px); /* 调整高度 */
|
||||
overflow-y: auto;
|
||||
padding: 0; /* 移除内边距 */
|
||||
margin: -24px -16px; /* 抵消父容器的 px-4 py-6 */
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.scroller {
|
||||
margin: -24px -40px; /* 抵消父容器的 lg:px-10 */
|
||||
}
|
||||
}
|
||||
|
||||
.grid-row {
|
||||
padding: 12px 16px;
|
||||
box-sizing: border-box;
|
||||
min-height: 128px; /* 确保最小高度 */
|
||||
}
|
||||
|
||||
/* 确保 RecycleScroller 的样式正确 */
|
||||
:deep(.vue-recycle-scroller) {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
:deep(.vue-recycle-scroller__item-wrapper) {
|
||||
flex: 1;
|
||||
box-sizing: border-box;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
:deep(.vue-recycle-scroller__item-view) {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
|
||||
23
src/vite-env.d.ts
vendored
23
src/vite-env.d.ts
vendored
@@ -21,3 +21,26 @@ declare interface IpcChannels {
|
||||
}
|
||||
|
||||
declare const __APP_VERSION__: string;
|
||||
|
||||
// vue-virtual-scroller type declarations
|
||||
declare module "vue-virtual-scroller" {
|
||||
import { DefineComponent } from "vue";
|
||||
|
||||
export const RecycleScroller: DefineComponent<{
|
||||
items: any[];
|
||||
itemSize: number;
|
||||
keyField?: string;
|
||||
direction?: "vertical" | "horizontal";
|
||||
buffer?: number;
|
||||
}>;
|
||||
|
||||
export const DynamicScroller: DefineComponent<{
|
||||
items: any[];
|
||||
minItemSize: number;
|
||||
keyField?: string;
|
||||
direction?: "vertical" | "horizontal";
|
||||
buffer?: number;
|
||||
}>;
|
||||
|
||||
export const DynamicScrollerItem: DefineComponent<{}>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user