From 0dedd0faf0ae60d59f48b3ba2d74b6573f1ce146 Mon Sep 17 00:00:00 2001
From: shenmo
Date: Sun, 29 Mar 2026 19:43:53 +0800
Subject: [PATCH] =?UTF-8?q?feat(=E7=BB=84=E4=BB=B6):=20=E6=B7=BB=E5=8A=A0?=
=?UTF-8?q?=E8=99=9A=E6=8B=9F=E6=BB=9A=E5=8A=A8=E4=BC=98=E5=8C=96=E5=BA=94?=
=?UTF-8?q?=E7=94=A8=E7=BD=91=E6=A0=BC=E6=80=A7=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
为AppGrid组件添加vue-virtual-scroller实现虚拟滚动功能,当应用数量超过50个时自动启用
更新package.json添加vue-virtual-scroller依赖
添加vue-virtual-scroller的类型声明
优化网格布局响应式处理,根据窗口宽度动态调整列数
---
package-lock.json | 73 ++++++++++++++--------
package.json | 3 +-
src/components/AppGrid.vue | 122 ++++++++++++++++++++++++++++++++++++-
src/vite-env.d.ts | 23 +++++++
4 files changed, 192 insertions(+), 29 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 63934464..dd2db2d4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -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",
diff --git a/package.json b/package.json
index aa7182c7..6318b4b9 100644
--- a/package.json
+++ b/package.json
@@ -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"
}
}
diff --git a/src/components/AppGrid.vue b/src/components/AppGrid.vue
index 5a7ae691..acc7485c 100644
--- a/src/components/AppGrid.vue
+++ b/src/components/AppGrid.vue
@@ -16,8 +16,10 @@
试试其他关键词,或检查拼写是否正确
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts
index 8a2c9c82..55420832 100644
--- a/src/vite-env.d.ts
+++ b/src/vite-env.d.ts
@@ -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<{}>;
+}