refactor: optimize Keep-Alive component rendering and data synchronization by introducing silent refresh states and fallback layout calculations.

This commit is contained in:
jxxghp
2026-05-17 14:06:05 +08:00
parent 348ae6b313
commit 0e005c3c7e
13 changed files with 197 additions and 78 deletions

View File

@@ -13,7 +13,7 @@ import PluginMixedSortCard from '@/components/cards/PluginMixedSortCard.vue'
import ProgressiveCardGrid from '@/components/misc/ProgressiveCardGrid.vue'
import { usePWA } from '@/composables/usePWA'
import { useDynamicHeaderTab } from '@/composables/useDynamicHeaderTab'
import { useKeepAliveRefresh } from '@/composables/useKeepAliveRefresh'
import { useKeepAliveRefresh, type KeepAliveRefreshContext } from '@/composables/useKeepAliveRefresh'
// 国际化
const { t } = useI18n()
@@ -740,9 +740,13 @@ const filterPlugins = computed(() => {
})
// 获取插件列表数据
async function fetchInstalledPlugins() {
async function fetchInstalledPlugins(context: KeepAliveRefreshContext = {}) {
const showLoading = !context.silent || !isRefreshed.value
try {
loading.value = true
if (showLoading) {
loading.value = true
}
dataList.value = await api.get('plugin/', {
params: {
state: 'installed',
@@ -754,14 +758,20 @@ async function fetchInstalledPlugins() {
} catch (error) {
console.error(error)
} finally {
loading.value = false
if (showLoading) {
loading.value = false
}
}
}
// 获取未安装插件列表数据
async function fetchUninstalledPlugins(force: boolean = false) {
async function fetchUninstalledPlugins(force: boolean = false, context: KeepAliveRefreshContext = {}) {
const showLoading = !context.silent || !isAppMarketLoaded.value
try {
loading.value = true
if (showLoading) {
loading.value = true
}
uninstalledList.value = await api.get('plugin/', {
params: {
state: 'market',
@@ -790,7 +800,9 @@ async function fetchUninstalledPlugins(force: boolean = false) {
} catch (error) {
console.error(error)
} finally {
loading.value = false
if (showLoading) {
loading.value = false
}
}
}
@@ -804,10 +816,10 @@ async function getPluginStatistics() {
}
// 加载所有数据
async function refreshData() {
await fetchInstalledPlugins()
await fetchUninstalledPlugins()
getPluginStatistics()
async function refreshData(context: KeepAliveRefreshContext = {}) {
await fetchInstalledPlugins(context)
await fetchUninstalledPlugins(false, context)
await getPluginStatistics()
// 重新加载文件夹配置,确保分身插件能正确显示在文件夹中
await loadPluginFolders()
}
@@ -876,26 +888,33 @@ function marketSettingDone() {
// 手动刷新插件市场
async function refreshMarket() {
isMarketRefreshing.value = true
const showMarketLoading = !isAppMarketLoaded.value
if (showMarketLoading) {
isMarketRefreshing.value = true
}
try {
await fetchUninstalledPlugins(true)
getPluginStatistics()
await fetchUninstalledPlugins(true, { silent: isAppMarketLoaded.value, source: 'manual' })
await getPluginStatistics()
} catch (error) {
console.error(error)
} finally {
isMarketRefreshing.value = false
if (showMarketLoading) {
isMarketRefreshing.value = false
}
}
}
async function refreshActiveTabData() {
async function refreshActiveTabData(context: KeepAliveRefreshContext = {}) {
if (sortMode.value || isDraggingSortMode.value) return
if (activeTab.value === 'market') {
await fetchUninstalledPlugins(false, context)
await getPluginStatistics()
return
}
await fetchInstalledPlugins()
getPluginStatistics()
await fetchInstalledPlugins(context)
await getPluginStatistics()
// 文件夹配置可能在其它入口被插件操作改变,重新进入时同步一次。
await loadPluginFolders()
}
@@ -968,7 +987,7 @@ const { refresh: refreshKeepAliveData } = useKeepAliveRefresh(refreshActiveTabDa
watch(activeTab, (newTab, oldTab) => {
if (!oldTab || newTab === oldTab) return
refreshKeepAliveData()
refreshKeepAliveData({ silent: true, source: 'tab' })
})
function openPluginSearchDialog() {
@@ -1698,10 +1717,13 @@ function onDragStartPlugin(evt: any) {
<VWindowItem value="market">
<transition name="fade-slide" appear>
<div>
<LoadingBanner v-if="!isAppMarketLoaded || isMarketRefreshing" class="mt-12" />
<LoadingBanner
v-if="!isAppMarketLoaded || (isMarketRefreshing && displayUninstalledList.length === 0)"
class="mt-12"
/>
<!-- 资源列表 -->
<VInfiniteScroll
v-if="isAppMarketLoaded && !isMarketRefreshing"
v-if="isAppMarketLoaded && !(isMarketRefreshing && displayUninstalledList.length === 0)"
mode="intersect"
side="end"
:items="displayUninstalledList"