refactor: standardize keep-alive data refreshing using useKeepAliveRefresh composable across views and dashboards

This commit is contained in:
jxxghp
2026-05-17 10:04:30 +08:00
parent 6900042cf7
commit 5e8489c620
16 changed files with 88 additions and 100 deletions

View File

@@ -4,6 +4,7 @@ import { hexToRgb } from '@layouts/utils'
import api from '@/api'
import { useI18n } from 'vue-i18n'
import { useBackground } from '@/composables/useBackground'
import { useKeepAliveRefresh } from '@/composables/useKeepAliveRefresh'
// 国际化
const { t } = useI18n()
@@ -29,8 +30,6 @@ const variableTheme = controlledComputed(
() => vuetifyTheme.current.value.variables,
)
const chartKey = ref(0)
// 时间序列
const series = ref([
{
@@ -123,18 +122,14 @@ async function loadCpuData() {
}
// 使用数据刷新定时器
const { loading } = useDataRefresh(
const { loading, refresh } = useDataRefresh(
'analytics-cpu',
loadCpuData,
2000, // 2秒间隔
true // 立即执行
)
onActivated(() => {
nextTick(() => {
chartKey.value += 1
})
})
useKeepAliveRefresh(refresh)
</script>
<template>
@@ -148,7 +143,7 @@ onActivated(() => {
<VCardTitle>CPU</VCardTitle>
</VCardItem>
<VCardText>
<VApexChart :key="chartKey" type="line" :options="chartOptions" :series="series" :height="150" />
<VApexChart type="line" :options="chartOptions" :series="series" :height="150" />
<p class="text-center font-weight-medium mb-0">{{ t('dashboard.current') }}{{ current }}%</p>
</VCardText>
</VCard>

View File

@@ -5,6 +5,7 @@ import api from '@/api'
import { formatBytes } from '@/@core/utils/formatters'
import { useI18n } from 'vue-i18n'
import { useBackground } from '@/composables/useBackground'
import { useKeepAliveRefresh } from '@/composables/useKeepAliveRefresh'
// 国际化
const { t } = useI18n()
@@ -30,8 +31,6 @@ const variableTheme = controlledComputed(
() => vuetifyTheme.current.value.variables,
)
const chartKey = ref(0)
// 时间序列
const series = ref([
{
@@ -128,19 +127,14 @@ async function loadMemoryData() {
}
// 使用数据刷新定时器
const { loading } = useDataRefresh(
const { loading, refresh } = useDataRefresh(
'analytics-memory',
loadMemoryData,
3000, // 3秒间隔
true // 立即执行
)
onActivated(() => {
// 使用nextTick确保DOM准备完成后再更新chartKey
nextTick(() => {
chartKey.value += 1
})
})
useKeepAliveRefresh(refresh)
</script>
<template>
@@ -154,7 +148,7 @@ onActivated(() => {
<VCardTitle>{{ t('dashboard.memory') }}</VCardTitle>
</VCardItem>
<VCardText>
<VApexChart :key="chartKey" type="area" :options="chartOptions" :series="series" :height="150" />
<VApexChart type="area" :options="chartOptions" :series="series" :height="150" />
<p class="text-center font-weight-medium mb-0">{{ t('dashboard.current') }}{{ formatBytes(usedMemory) }}</p>
</VCardText>
</VCard>

View File

@@ -4,6 +4,7 @@ import { hexToRgb } from '@layouts/utils'
import api from '@/api'
import { useI18n } from 'vue-i18n'
import { useBackground } from '@/composables/useBackground'
import { useKeepAliveRefresh } from '@/composables/useKeepAliveRefresh'
// 国际化
const { t } = useI18n()
@@ -29,8 +30,6 @@ const variableTheme = controlledComputed(
() => vuetifyTheme.current.value.variables,
)
const chartKey = ref(0)
// 时间序列 - 上行和下行流量
const series = ref([
{
@@ -161,18 +160,14 @@ async function getNetworkUsage() {
}
// 使用数据刷新定时器
useDataRefresh(
const { refresh } = useDataRefresh(
'dashboard-network',
getNetworkUsage,
2000, // 2秒间隔
true // 立即执行
)
onActivated(() => {
nextTick(() => {
chartKey.value += 1
})
})
useKeepAliveRefresh(refresh)
</script>
<template>
@@ -186,7 +181,7 @@ onActivated(() => {
<VCardTitle>{{ t('dashboard.network') }}</VCardTitle>
</VCardItem>
<VCardText>
<VApexChart :key="chartKey" type="line" :options="chartOptions" :series="series" :height="150" />
<VApexChart type="line" :options="chartOptions" :series="series" :height="150" />
<div class="d-flex justify-space-between">
<p class="text-center font-weight-medium mb-0">
<span class="text-warning">{{ t('dashboard.upload') }}</span

View File

@@ -362,9 +362,6 @@ const draggableFolderPlugins = ref<Plugin[]>([])
// 是否正在拖拽排序中
const isDraggingSortMode = ref(false)
// 插件市场分页 key重置后让 VInfiniteScroll 重新触发首屏加载。
const marketInfiniteKey = ref(0)
// 显示的文件夹列表(按排序显示)
const displayedFolders = computed(() => {
if (currentFolder.value) return [] // 在文件夹内不显示其他文件夹
@@ -810,7 +807,6 @@ async function getPluginStatistics() {
async function refreshData() {
await fetchInstalledPlugins()
await fetchUninstalledPlugins()
marketInfiniteKey.value++
getPluginStatistics()
// 重新加载文件夹配置,确保分身插件能正确显示在文件夹中
await loadPluginFolders()
@@ -884,7 +880,6 @@ async function refreshMarket() {
try {
await fetchUninstalledPlugins(true)
getPluginStatistics()
marketInfiniteKey.value++
} catch (error) {
console.error(error)
} finally {
@@ -896,16 +891,10 @@ async function refreshActiveTabData() {
if (sortMode.value || isDraggingSortMode.value) return
if (activeTab.value === 'market') {
isAppMarketLoaded.value = false
await fetchInstalledPlugins()
await fetchUninstalledPlugins()
getPluginStatistics()
marketInfiniteKey.value++
return
}
await fetchInstalledPlugins()
await fetchUninstalledPlugins()
getPluginStatistics()
// 文件夹配置可能在其它入口被插件操作改变,重新进入时同步一次。
await loadPluginFolders()
@@ -1716,7 +1705,6 @@ function onDragStartPlugin(evt: any) {
mode="intersect"
side="end"
:items="displayUninstalledList"
:key="marketInfiniteKey"
@load="loadMarketMore"
class="overflow-visible"
>

View File

@@ -8,6 +8,7 @@ import ProgressiveCardGrid from '@/components/misc/ProgressiveCardGrid.vue'
import { useUserStore } from '@/stores'
import { useI18n } from 'vue-i18n'
import { useBackground } from '@/composables/useBackground'
import { useKeepAliveRefresh } from '@/composables/useKeepAliveRefresh'
// 国际化
const { t } = useI18n()
@@ -16,6 +17,7 @@ const { useDataRefresh } = useBackground()
// 定义输入参数
const props = defineProps<{
name: string
active?: boolean
}>()
// 用户 Store
@@ -63,6 +65,10 @@ const { loading: dataLoading } = useDataRefresh(
3000, // 3秒间隔
true // 立即执行
)
useKeepAliveRefresh(fetchData, {
active: computed(() => props.active !== false),
})
</script>
<template>

View File

@@ -306,9 +306,11 @@ watch(
}, 1000),
)
// 获取订阅列表数据
async function fetchData(page = currentPage.value, count = itemsPerPage.value) {
loading.value = true
// 获取历史记录数据keep-alive 重新进入时可静默刷新,避免表格出现重新加载感。
async function fetchData(page = currentPage.value, count = itemsPerPage.value, options: { silent?: boolean } = {}) {
if (!options.silent) {
loading.value = true
}
try {
const result: { [key: string]: any } = await api.get('history/transfer', {
@@ -326,8 +328,11 @@ async function fetchData(page = currentPage.value, count = itemsPerPage.value) {
)
} catch (error) {
console.error(error)
} finally {
if (!options.silent) {
loading.value = false
}
}
loading.value = false
}
// 根据 type 返回不同的图标
@@ -761,7 +766,7 @@ onActivated(() => {
}
if (!loading.value) {
fetchData()
fetchData(currentPage.value, itemsPerPage.value, { silent: true })
}
})

View File

@@ -4,7 +4,6 @@ import type { MediaInfo } from '@/api/types'
import MediaCard from '@/components/cards/MediaCard.vue'
import NoDataFound from '@/components/NoDataFound.vue'
import ProgressiveCardGrid from '@/components/misc/ProgressiveCardGrid.vue'
import { useKeepAliveRefresh } from '@/composables/useKeepAliveRefresh'
import { useI18n } from 'vue-i18n'
// 国际化
@@ -13,10 +12,6 @@ const { t } = useI18n()
// 输入参数
const props = defineProps({
type: String,
active: {
type: Boolean,
default: true,
},
})
// 判断是否有滚动条
@@ -116,10 +111,6 @@ watch(
{ deep: true },
)
useKeepAliveRefresh(resetData, {
active: computed(() => props.active),
})
// 拼装参数
function getParams() {
let params: { [key: string]: any } = {

View File

@@ -4,7 +4,6 @@ import type { SubscribeShare } from '@/api/types'
import NoDataFound from '@/components/NoDataFound.vue'
import SubscribeShareCard from '@/components/cards/SubscribeShareCard.vue'
import ProgressiveCardGrid from '@/components/misc/ProgressiveCardGrid.vue'
import { useKeepAliveRefresh } from '@/composables/useKeepAliveRefresh'
import { useI18n } from 'vue-i18n'
// 国际化
@@ -14,10 +13,6 @@ const { t } = useI18n()
const props = defineProps({
// 过滤关键字
keyword: String,
active: {
type: Boolean,
default: true,
},
})
// 判断是否有滚动条
@@ -129,10 +124,6 @@ const isRefreshed = ref(false)
const dataList = ref<SubscribeShare[]>([])
const currData = ref<SubscribeShare[]>([])
useKeepAliveRefresh(resetData, {
active: computed(() => props.active),
})
// 拼装参数
function getParams() {
let params: { [key: string]: any } = {

View File

@@ -6,6 +6,7 @@ import WorkflowTaskCard from '@/components/cards/WorkflowTaskCard.vue'
import NoDataFound from '@/components/NoDataFound.vue'
import ProgressiveCardGrid from '@/components/misc/ProgressiveCardGrid.vue'
import { useI18n } from 'vue-i18n'
import { useKeepAliveRefresh } from '@/composables/useKeepAliveRefresh'
// 国际化
const { t } = useI18n()
@@ -52,9 +53,7 @@ onMounted(() => {
fetchData()
})
onActivated(() => {
fetchData()
})
useKeepAliveRefresh(fetchData)
function openAddDialog() {
addDialog.value = true
@@ -62,6 +61,7 @@ function openAddDialog() {
defineExpose({
openAddDialog,
refresh: fetchData,
})
</script>
<template>

View File

@@ -146,9 +146,8 @@ function removeData(id: string) {
dataList.value = dataList.value.filter(item => item.id !== id)
}
onActivated(() => {
onMounted(() => {
loadEventTypes()
fetchData({ done: () => {} })
})
</script>