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",
|
"name": "spark-store",
|
||||||
"version": "4.9.9alpha4",
|
"version": "5.0.0beta1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "spark-store",
|
"name": "spark-store",
|
||||||
"version": "4.9.9alpha4",
|
"version": "5.0.0beta1",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tailwindcss/vite": "^4.1.18",
|
"@tailwindcss/vite": "^4.1.18",
|
||||||
"axios": "^1.13.2",
|
"axios": "^1.13.2",
|
||||||
"pino": "^10.3.0",
|
"pino": "^10.3.0",
|
||||||
"tailwindcss": "^4.1.18"
|
"tailwindcss": "^4.1.18",
|
||||||
|
"vue-virtual-scroller": "^2.0.0-beta.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@dotenvx/dotenvx": "^1.51.4",
|
"@dotenvx/dotenvx": "^1.51.4",
|
||||||
@@ -114,7 +115,6 @@
|
|||||||
"version": "7.27.1",
|
"version": "7.27.1",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
|
||||||
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
|
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
@@ -123,7 +123,6 @@
|
|||||||
"version": "7.28.5",
|
"version": "7.28.5",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
|
||||||
"integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
|
"integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
@@ -132,7 +131,6 @@
|
|||||||
"version": "7.29.0",
|
"version": "7.29.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz",
|
||||||
"integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==",
|
"integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/types": "^7.29.0"
|
"@babel/types": "^7.29.0"
|
||||||
},
|
},
|
||||||
@@ -156,7 +154,6 @@
|
|||||||
"version": "7.29.0",
|
"version": "7.29.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
|
||||||
"integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
|
"integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/helper-string-parser": "^7.27.1",
|
"@babel/helper-string-parser": "^7.27.1",
|
||||||
"@babel/helper-validator-identifier": "^7.28.5"
|
"@babel/helper-validator-identifier": "^7.28.5"
|
||||||
@@ -3089,7 +3086,6 @@
|
|||||||
"version": "3.5.30",
|
"version": "3.5.30",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.30.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.30.tgz",
|
||||||
"integrity": "sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==",
|
"integrity": "sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.29.0",
|
"@babel/parser": "^7.29.0",
|
||||||
"@vue/shared": "3.5.30",
|
"@vue/shared": "3.5.30",
|
||||||
@@ -3102,7 +3098,6 @@
|
|||||||
"version": "7.0.1",
|
"version": "7.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
|
||||||
"integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
|
"integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.12"
|
"node": ">=0.12"
|
||||||
},
|
},
|
||||||
@@ -3113,14 +3108,12 @@
|
|||||||
"node_modules/@vue/compiler-core/node_modules/estree-walker": {
|
"node_modules/@vue/compiler-core/node_modules/estree-walker": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-dom": {
|
"node_modules/@vue/compiler-dom": {
|
||||||
"version": "3.5.30",
|
"version": "3.5.30",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.30.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.30.tgz",
|
||||||
"integrity": "sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==",
|
"integrity": "sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-core": "3.5.30",
|
"@vue/compiler-core": "3.5.30",
|
||||||
"@vue/shared": "3.5.30"
|
"@vue/shared": "3.5.30"
|
||||||
@@ -3130,7 +3123,6 @@
|
|||||||
"version": "3.5.30",
|
"version": "3.5.30",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.30.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.30.tgz",
|
||||||
"integrity": "sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==",
|
"integrity": "sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/parser": "^7.29.0",
|
"@babel/parser": "^7.29.0",
|
||||||
"@vue/compiler-core": "3.5.30",
|
"@vue/compiler-core": "3.5.30",
|
||||||
@@ -3146,14 +3138,12 @@
|
|||||||
"node_modules/@vue/compiler-sfc/node_modules/estree-walker": {
|
"node_modules/@vue/compiler-sfc/node_modules/estree-walker": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/@vue/compiler-ssr": {
|
"node_modules/@vue/compiler-ssr": {
|
||||||
"version": "3.5.30",
|
"version": "3.5.30",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.30.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.30.tgz",
|
||||||
"integrity": "sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==",
|
"integrity": "sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.5.30",
|
"@vue/compiler-dom": "3.5.30",
|
||||||
"@vue/shared": "3.5.30"
|
"@vue/shared": "3.5.30"
|
||||||
@@ -3178,7 +3168,6 @@
|
|||||||
"version": "3.5.30",
|
"version": "3.5.30",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.30.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.30.tgz",
|
||||||
"integrity": "sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==",
|
"integrity": "sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/shared": "3.5.30"
|
"@vue/shared": "3.5.30"
|
||||||
}
|
}
|
||||||
@@ -3187,7 +3176,6 @@
|
|||||||
"version": "3.5.30",
|
"version": "3.5.30",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.30.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.30.tgz",
|
||||||
"integrity": "sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==",
|
"integrity": "sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "3.5.30",
|
"@vue/reactivity": "3.5.30",
|
||||||
"@vue/shared": "3.5.30"
|
"@vue/shared": "3.5.30"
|
||||||
@@ -3197,7 +3185,6 @@
|
|||||||
"version": "3.5.30",
|
"version": "3.5.30",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.30.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.30.tgz",
|
||||||
"integrity": "sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==",
|
"integrity": "sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/reactivity": "3.5.30",
|
"@vue/reactivity": "3.5.30",
|
||||||
"@vue/runtime-core": "3.5.30",
|
"@vue/runtime-core": "3.5.30",
|
||||||
@@ -3209,7 +3196,6 @@
|
|||||||
"version": "3.5.30",
|
"version": "3.5.30",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.30.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.30.tgz",
|
||||||
"integrity": "sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==",
|
"integrity": "sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-ssr": "3.5.30",
|
"@vue/compiler-ssr": "3.5.30",
|
||||||
"@vue/shared": "3.5.30"
|
"@vue/shared": "3.5.30"
|
||||||
@@ -3221,8 +3207,7 @@
|
|||||||
"node_modules/@vue/shared": {
|
"node_modules/@vue/shared": {
|
||||||
"version": "3.5.30",
|
"version": "3.5.30",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.30.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.30.tgz",
|
||||||
"integrity": "sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==",
|
"integrity": "sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/@vue/test-utils": {
|
"node_modules/@vue/test-utils": {
|
||||||
"version": "2.4.6",
|
"version": "2.4.6",
|
||||||
@@ -4442,8 +4427,7 @@
|
|||||||
"node_modules/csstype": {
|
"node_modules/csstype": {
|
||||||
"version": "3.2.3",
|
"version": "3.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
|
||||||
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/data-urls": {
|
"node_modules/data-urls": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
@@ -7961,6 +7945,12 @@
|
|||||||
"node": ">= 8"
|
"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": {
|
"node_modules/mkdirp": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||||
@@ -10073,7 +10063,7 @@
|
|||||||
"version": "5.9.3",
|
"version": "5.9.3",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
@@ -11514,7 +11504,6 @@
|
|||||||
"version": "3.5.30",
|
"version": "3.5.30",
|
||||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.30.tgz",
|
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.30.tgz",
|
||||||
"integrity": "sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==",
|
"integrity": "sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/compiler-dom": "3.5.30",
|
"@vue/compiler-dom": "3.5.30",
|
||||||
"@vue/compiler-sfc": "3.5.30",
|
"@vue/compiler-sfc": "3.5.30",
|
||||||
@@ -11561,6 +11550,24 @@
|
|||||||
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0"
|
"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": {
|
"node_modules/vue-tsc": {
|
||||||
"version": "3.2.5",
|
"version": "3.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-3.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-3.2.5.tgz",
|
||||||
@@ -11577,6 +11584,20 @@
|
|||||||
"typescript": ">=5.0.0"
|
"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": {
|
"node_modules/w3c-xmlserializer": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
|
||||||
|
|||||||
@@ -75,6 +75,7 @@
|
|||||||
"@tailwindcss/vite": "^4.1.18",
|
"@tailwindcss/vite": "^4.1.18",
|
||||||
"axios": "^1.13.2",
|
"axios": "^1.13.2",
|
||||||
"pino": "^10.3.0",
|
"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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 应用数量较少时,使用普通网格 -->
|
||||||
<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"
|
class="grid gap-4 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4"
|
||||||
>
|
>
|
||||||
<AppCard
|
<AppCard
|
||||||
@@ -28,6 +30,28 @@
|
|||||||
@open-detail="$emit('open-detail', app)"
|
@open-detail="$emit('open-detail', app)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</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-else class="grid gap-4 sm:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4">
|
||||||
<div
|
<div
|
||||||
v-for="n in 8"
|
v-for="n in 8"
|
||||||
@@ -53,10 +77,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<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 AppCard from "./AppCard.vue";
|
||||||
import type { App } from "../global/typedefinition";
|
import type { App } from "../global/typedefinition";
|
||||||
|
|
||||||
defineProps<{
|
const props = defineProps<{
|
||||||
apps: App[];
|
apps: App[];
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
storeFilter?: "spark" | "apm" | "both";
|
storeFilter?: "spark" | "apm" | "both";
|
||||||
@@ -65,4 +92,95 @@ defineProps<{
|
|||||||
defineEmits<{
|
defineEmits<{
|
||||||
(e: "open-detail", app: App): void;
|
(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>
|
</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;
|
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