mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-06 08:06:43 +08:00
feat: introduce useKeepAliveRefresh composable to manage tab data synchronization and lifecycle refresh logic
This commit is contained in:
@@ -31,6 +31,10 @@ const props = defineProps({
|
|||||||
type: Array as PropType<FileItem[]>,
|
type: Array as PropType<FileItem[]>,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
|
active: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// 对外事件
|
// 对外事件
|
||||||
@@ -308,6 +312,7 @@ function stopDrag() {
|
|||||||
:refreshpending="refreshPending"
|
:refreshpending="refreshPending"
|
||||||
:sort="sort"
|
:sort="sort"
|
||||||
:showTree="showDirTree"
|
:showTree="showDirTree"
|
||||||
|
:active="active"
|
||||||
:style="{ flex: 1 }"
|
:style="{ flex: 1 }"
|
||||||
@pathchanged="pathChanged"
|
@pathchanged="pathChanged"
|
||||||
@loading="loadingChanged"
|
@loading="loadingChanged"
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { useI18n } from 'vue-i18n'
|
|||||||
import { useBackgroundOptimization } from '@/composables/useBackgroundOptimization'
|
import { useBackgroundOptimization } from '@/composables/useBackgroundOptimization'
|
||||||
import { usePWA } from '@/composables/usePWA'
|
import { usePWA } from '@/composables/usePWA'
|
||||||
import { useAvailableHeight } from '@/composables/useAvailableHeight'
|
import { useAvailableHeight } from '@/composables/useAvailableHeight'
|
||||||
|
import { useKeepAliveRefresh } from '@/composables/useKeepAliveRefresh'
|
||||||
|
|
||||||
// 国际化
|
// 国际化
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
@@ -43,6 +44,10 @@ const inProps = defineProps({
|
|||||||
},
|
},
|
||||||
sort: String,
|
sort: String,
|
||||||
showTree: Boolean,
|
showTree: Boolean,
|
||||||
|
active: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// 对外事件
|
// 对外事件
|
||||||
@@ -235,28 +240,33 @@ async function list_files() {
|
|||||||
const prevURI = takeURISnapshot();
|
const prevURI = takeURISnapshot();
|
||||||
emit('loading', true)
|
emit('loading', true)
|
||||||
|
|
||||||
// 参数
|
try {
|
||||||
const url = inProps.endpoints?.list.url.replace(/{sort}/g, inProps.sort || 'name')
|
// 参数
|
||||||
|
const url = inProps.endpoints?.list.url.replace(/{sort}/g, inProps.sort || 'name')
|
||||||
|
|
||||||
const config: AxiosRequestConfig<FileItem> = {
|
const config: AxiosRequestConfig<FileItem> = {
|
||||||
url,
|
url,
|
||||||
method: inProps.endpoints?.list.method || 'get',
|
method: inProps.endpoints?.list.method || 'get',
|
||||||
data: inProps.item,
|
data: inProps.item,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载数据
|
||||||
|
const data = ((await inProps.axios.request<FileItem[], FileItem[]>(config))) ?? []
|
||||||
|
// 如果当前路径已经变化,则放弃此次加载结果
|
||||||
|
if (prevURI !== takeURISnapshot()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
items.value = data
|
||||||
|
syncSelectedItems(data)
|
||||||
|
|
||||||
|
// 通知父组件文件列表更新
|
||||||
|
emit('items-updated', items.value)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
} finally {
|
||||||
|
emit('loading', false)
|
||||||
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载数据
|
|
||||||
const data = ((await inProps.axios.request<FileItem[], FileItem[]>(config))) ?? []
|
|
||||||
// 如果当前路径已经变化,则放弃此次加载结果
|
|
||||||
if (prevURI !== takeURISnapshot()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
items.value = data
|
|
||||||
syncSelectedItems(data)
|
|
||||||
emit('loading', false)
|
|
||||||
loading.value = false
|
|
||||||
|
|
||||||
// 通知父组件文件列表更新
|
|
||||||
emit('items-updated', items.value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除项目
|
// 删除项目
|
||||||
@@ -667,6 +677,10 @@ onMounted(() => {
|
|||||||
list_files()
|
list_files()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
useKeepAliveRefresh(list_files, {
|
||||||
|
active: computed(() => inProps.active),
|
||||||
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
revokeCurrentImgLink()
|
revokeCurrentImgLink()
|
||||||
stopLoadingProgress()
|
stopLoadingProgress()
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
import { nextTick, onActivated, onMounted, toValue, watch, type MaybeRefOrGetter } from 'vue'
|
||||||
|
|
||||||
|
type RefreshHandler = () => void | Promise<void>
|
||||||
|
|
||||||
|
interface KeepAliveRefreshOptions {
|
||||||
|
/**
|
||||||
|
* 当前内容是否处于可见状态。
|
||||||
|
* keep-alive 会激活整棵缓存树,tab 内组件需要用它避免后台标签页也刷新。
|
||||||
|
*/
|
||||||
|
active?: MaybeRefOrGetter<boolean>
|
||||||
|
/** 是否在 keep-alive 页面重新进入时刷新。 */
|
||||||
|
refreshOnActivated?: boolean
|
||||||
|
/** 是否在 tab 从隐藏切回可见时刷新。 */
|
||||||
|
refreshOnTabActivated?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* keep-alive 页面复用实例时不会重新 mounted,这里统一补上重新进入和重新选中 tab 的刷新。
|
||||||
|
*/
|
||||||
|
export function useKeepAliveRefresh(refresh: RefreshHandler, options: KeepAliveRefreshOptions = {}) {
|
||||||
|
let mounted = false
|
||||||
|
let activatedCount = 0
|
||||||
|
let refreshing = false
|
||||||
|
let pendingRefresh = false
|
||||||
|
|
||||||
|
const isActive = () => options.active === undefined || Boolean(toValue(options.active))
|
||||||
|
|
||||||
|
async function runRefresh() {
|
||||||
|
if (!isActive()) return
|
||||||
|
|
||||||
|
// 避免路由激活和 tab 激活在同一轮里叠加出并发请求。
|
||||||
|
if (refreshing) {
|
||||||
|
pendingRefresh = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshing = true
|
||||||
|
try {
|
||||||
|
await refresh()
|
||||||
|
} finally {
|
||||||
|
refreshing = false
|
||||||
|
|
||||||
|
if (pendingRefresh) {
|
||||||
|
pendingRefresh = false
|
||||||
|
await runRefresh()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function requestRefresh() {
|
||||||
|
void nextTick(runRefresh)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
mounted = true
|
||||||
|
})
|
||||||
|
|
||||||
|
if (options.refreshOnActivated !== false) {
|
||||||
|
onActivated(() => {
|
||||||
|
activatedCount += 1
|
||||||
|
|
||||||
|
// KeepAlive 首次挂载也会触发 activated,初始加载交给页面自己的 mounted 逻辑。
|
||||||
|
if (activatedCount === 1) return
|
||||||
|
|
||||||
|
requestRefresh()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.active !== undefined && options.refreshOnTabActivated !== false) {
|
||||||
|
watch(
|
||||||
|
() => Boolean(toValue(options.active)),
|
||||||
|
(active, oldActive) => {
|
||||||
|
if (!mounted || !active || oldActive !== false) return
|
||||||
|
|
||||||
|
requestRefresh()
|
||||||
|
},
|
||||||
|
{ flush: 'post' },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
refresh: runRefresh,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -287,6 +287,7 @@ onMounted(() => {
|
|||||||
:keyword="subscribeFilter"
|
:keyword="subscribeFilter"
|
||||||
:status-filter="subscribeStatusFilter ?? ''"
|
:status-filter="subscribeStatusFilter ?? ''"
|
||||||
:sort-mode="subscribeSortMode"
|
:sort-mode="subscribeSortMode"
|
||||||
|
:active="activeTab === 'mysub'"
|
||||||
@update:sort-mode="subscribeSortMode = $event"
|
@update:sort-mode="subscribeSortMode = $event"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -295,14 +296,14 @@ onMounted(() => {
|
|||||||
<VWindowItem value="popular">
|
<VWindowItem value="popular">
|
||||||
<transition name="fade-slide" appear>
|
<transition name="fade-slide" appear>
|
||||||
<div>
|
<div>
|
||||||
<SubscribePopularView :type="subType" />
|
<SubscribePopularView :type="subType" :active="activeTab === 'popular'" />
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</VWindowItem>
|
</VWindowItem>
|
||||||
<VWindowItem value="share">
|
<VWindowItem value="share">
|
||||||
<transition name="fade-slide" appear>
|
<transition name="fade-slide" appear>
|
||||||
<div>
|
<div>
|
||||||
<SubscribeShareView :keyword="shareKeyword" />
|
<SubscribeShareView :keyword="shareKeyword" :active="activeTab === 'share'" />
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</VWindowItem>
|
</VWindowItem>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import PluginMixedSortCard from '@/components/cards/PluginMixedSortCard.vue'
|
|||||||
import ProgressiveCardGrid from '@/components/misc/ProgressiveCardGrid.vue'
|
import ProgressiveCardGrid from '@/components/misc/ProgressiveCardGrid.vue'
|
||||||
import { usePWA } from '@/composables/usePWA'
|
import { usePWA } from '@/composables/usePWA'
|
||||||
import { useDynamicHeaderTab } from '@/composables/useDynamicHeaderTab'
|
import { useDynamicHeaderTab } from '@/composables/useDynamicHeaderTab'
|
||||||
|
import { useKeepAliveRefresh } from '@/composables/useKeepAliveRefresh'
|
||||||
|
|
||||||
// 国际化
|
// 国际化
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
@@ -361,6 +362,9 @@ const draggableFolderPlugins = ref<Plugin[]>([])
|
|||||||
// 是否正在拖拽排序中
|
// 是否正在拖拽排序中
|
||||||
const isDraggingSortMode = ref(false)
|
const isDraggingSortMode = ref(false)
|
||||||
|
|
||||||
|
// 插件市场分页 key,重置后让 VInfiniteScroll 重新触发首屏加载。
|
||||||
|
const marketInfiniteKey = ref(0)
|
||||||
|
|
||||||
// 显示的文件夹列表(按排序显示)
|
// 显示的文件夹列表(按排序显示)
|
||||||
const displayedFolders = computed(() => {
|
const displayedFolders = computed(() => {
|
||||||
if (currentFolder.value) return [] // 在文件夹内不显示其他文件夹
|
if (currentFolder.value) return [] // 在文件夹内不显示其他文件夹
|
||||||
@@ -749,10 +753,11 @@ async function fetchInstalledPlugins() {
|
|||||||
})
|
})
|
||||||
// 排序
|
// 排序
|
||||||
sortPluginOrder()
|
sortPluginOrder()
|
||||||
loading.value = false
|
|
||||||
isRefreshed.value = true
|
isRefreshed.value = true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -776,7 +781,6 @@ async function fetchUninstalledPlugins(force: boolean = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loading.value = false
|
|
||||||
isRefreshed.value = true
|
isRefreshed.value = true
|
||||||
// 更新插件市场列表
|
// 更新插件市场列表
|
||||||
// 排除已安装且有更新的,上面的问题在于"本地存在未安装的旧版本插件且云端有更新时"不会在插件市场展示
|
// 排除已安装且有更新的,上面的问题在于"本地存在未安装的旧版本插件且云端有更新时"不会在插件市场展示
|
||||||
@@ -788,6 +792,8 @@ async function fetchUninstalledPlugins(force: boolean = false) {
|
|||||||
isAppMarketLoaded.value = true
|
isAppMarketLoaded.value = true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -804,6 +810,7 @@ async function getPluginStatistics() {
|
|||||||
async function refreshData() {
|
async function refreshData() {
|
||||||
await fetchInstalledPlugins()
|
await fetchInstalledPlugins()
|
||||||
await fetchUninstalledPlugins()
|
await fetchUninstalledPlugins()
|
||||||
|
marketInfiniteKey.value++
|
||||||
getPluginStatistics()
|
getPluginStatistics()
|
||||||
// 重新加载文件夹配置,确保分身插件能正确显示在文件夹中
|
// 重新加载文件夹配置,确保分身插件能正确显示在文件夹中
|
||||||
await loadPluginFolders()
|
await loadPluginFolders()
|
||||||
@@ -877,6 +884,7 @@ async function refreshMarket() {
|
|||||||
try {
|
try {
|
||||||
await fetchUninstalledPlugins(true)
|
await fetchUninstalledPlugins(true)
|
||||||
getPluginStatistics()
|
getPluginStatistics()
|
||||||
|
marketInfiniteKey.value++
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
} finally {
|
} finally {
|
||||||
@@ -884,6 +892,25 @@ async function refreshMarket() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
function parseLocalRepoPath(repoUrl: string | undefined) {
|
function parseLocalRepoPath(repoUrl: string | undefined) {
|
||||||
if (!repoUrl?.startsWith('local://')) return ''
|
if (!repoUrl?.startsWith('local://')) return ''
|
||||||
|
|
||||||
@@ -947,6 +974,14 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const { refresh: refreshKeepAliveData } = useKeepAliveRefresh(refreshActiveTabData)
|
||||||
|
|
||||||
|
watch(activeTab, (newTab, oldTab) => {
|
||||||
|
if (!oldTab || newTab === oldTab) return
|
||||||
|
|
||||||
|
refreshKeepAliveData()
|
||||||
|
})
|
||||||
|
|
||||||
function openPluginSearchDialog() {
|
function openPluginSearchDialog() {
|
||||||
SearchDialog.value = true
|
SearchDialog.value = true
|
||||||
}
|
}
|
||||||
@@ -1681,6 +1716,7 @@ function onDragStartPlugin(evt: any) {
|
|||||||
mode="intersect"
|
mode="intersect"
|
||||||
side="end"
|
side="end"
|
||||||
:items="displayUninstalledList"
|
:items="displayUninstalledList"
|
||||||
|
:key="marketInfiniteKey"
|
||||||
@load="loadMarketMore"
|
@load="loadMarketMore"
|
||||||
class="overflow-visible"
|
class="overflow-visible"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { useUserStore } from '@/stores'
|
|||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useToast } from 'vue-toastification'
|
import { useToast } from 'vue-toastification'
|
||||||
import { useConfirm } from '@/composables/useConfirm'
|
import { useConfirm } from '@/composables/useConfirm'
|
||||||
|
import { useKeepAliveRefresh } from '@/composables/useKeepAliveRefresh'
|
||||||
|
|
||||||
// 国际化
|
// 国际化
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
@@ -37,6 +38,10 @@ const props = defineProps({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
active: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -413,10 +418,8 @@ onUnmounted(() => {
|
|||||||
window.removeEventListener('toggle-batch-mode', toggleBatchMode)
|
window.removeEventListener('toggle-batch-mode', toggleBatchMode)
|
||||||
})
|
})
|
||||||
|
|
||||||
onActivated(async () => {
|
useKeepAliveRefresh(fetchData, {
|
||||||
if (!loading.value) {
|
active: computed(() => props.active),
|
||||||
fetchData()
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import type { MediaInfo } from '@/api/types'
|
|||||||
import MediaCard from '@/components/cards/MediaCard.vue'
|
import MediaCard from '@/components/cards/MediaCard.vue'
|
||||||
import NoDataFound from '@/components/NoDataFound.vue'
|
import NoDataFound from '@/components/NoDataFound.vue'
|
||||||
import ProgressiveCardGrid from '@/components/misc/ProgressiveCardGrid.vue'
|
import ProgressiveCardGrid from '@/components/misc/ProgressiveCardGrid.vue'
|
||||||
|
import { useKeepAliveRefresh } from '@/composables/useKeepAliveRefresh'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
// 国际化
|
// 国际化
|
||||||
@@ -12,6 +13,10 @@ const { t } = useI18n()
|
|||||||
// 输入参数
|
// 输入参数
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
|
active: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// 判断是否有滚动条
|
// 判断是否有滚动条
|
||||||
@@ -47,6 +52,13 @@ const filterParams = reactive({
|
|||||||
// 当前Key(用于重新加载数据)
|
// 当前Key(用于重新加载数据)
|
||||||
const currentKey = ref(0)
|
const currentKey = ref(0)
|
||||||
|
|
||||||
|
function resetData() {
|
||||||
|
dataList.value = []
|
||||||
|
page.value = 1
|
||||||
|
isRefreshed.value = false
|
||||||
|
currentKey.value++
|
||||||
|
}
|
||||||
|
|
||||||
// TMDB电影风格字典
|
// TMDB电影风格字典
|
||||||
const tmdbMovieGenreDict: Record<string, string> = {
|
const tmdbMovieGenreDict: Record<string, string> = {
|
||||||
'28': t('tmdb.genreType.action'),
|
'28': t('tmdb.genreType.action'),
|
||||||
@@ -99,15 +111,15 @@ const currentGenreDict = computed(() => {
|
|||||||
watch(
|
watch(
|
||||||
filterParams,
|
filterParams,
|
||||||
() => {
|
() => {
|
||||||
// 重置数据
|
resetData()
|
||||||
dataList.value = []
|
|
||||||
page.value = 1
|
|
||||||
isRefreshed.value = false
|
|
||||||
currentKey.value++
|
|
||||||
},
|
},
|
||||||
{ deep: true },
|
{ deep: true },
|
||||||
)
|
)
|
||||||
|
|
||||||
|
useKeepAliveRefresh(resetData, {
|
||||||
|
active: computed(() => props.active),
|
||||||
|
})
|
||||||
|
|
||||||
// 拼装参数
|
// 拼装参数
|
||||||
function getParams() {
|
function getParams() {
|
||||||
let params: { [key: string]: any } = {
|
let params: { [key: string]: any } = {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import type { SubscribeShare } from '@/api/types'
|
|||||||
import NoDataFound from '@/components/NoDataFound.vue'
|
import NoDataFound from '@/components/NoDataFound.vue'
|
||||||
import SubscribeShareCard from '@/components/cards/SubscribeShareCard.vue'
|
import SubscribeShareCard from '@/components/cards/SubscribeShareCard.vue'
|
||||||
import ProgressiveCardGrid from '@/components/misc/ProgressiveCardGrid.vue'
|
import ProgressiveCardGrid from '@/components/misc/ProgressiveCardGrid.vue'
|
||||||
|
import { useKeepAliveRefresh } from '@/composables/useKeepAliveRefresh'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
// 国际化
|
// 国际化
|
||||||
@@ -13,6 +14,10 @@ const { t } = useI18n()
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
// 过滤关键字
|
// 过滤关键字
|
||||||
keyword: String,
|
keyword: String,
|
||||||
|
active: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// 判断是否有滚动条
|
// 判断是否有滚动条
|
||||||
@@ -40,6 +45,13 @@ const filterParams = reactive({
|
|||||||
// 当前Key(用于重新加载数据)
|
// 当前Key(用于重新加载数据)
|
||||||
const currentKey = ref(0)
|
const currentKey = ref(0)
|
||||||
|
|
||||||
|
function resetData() {
|
||||||
|
dataList.value = []
|
||||||
|
page.value = 1
|
||||||
|
isRefreshed.value = false
|
||||||
|
currentKey.value++
|
||||||
|
}
|
||||||
|
|
||||||
// TMDB电影风格字典
|
// TMDB电影风格字典
|
||||||
const tmdbMovieGenreDict: Record<string, string> = {
|
const tmdbMovieGenreDict: Record<string, string> = {
|
||||||
'28': t('tmdb.genreType.action'),
|
'28': t('tmdb.genreType.action'),
|
||||||
@@ -94,11 +106,7 @@ watch(
|
|||||||
() => props.keyword,
|
() => props.keyword,
|
||||||
newKeyword => {
|
newKeyword => {
|
||||||
keyword.value = newKeyword || ''
|
keyword.value = newKeyword || ''
|
||||||
// 重置页码和数据
|
resetData()
|
||||||
page.value = 1
|
|
||||||
dataList.value = []
|
|
||||||
isRefreshed.value = false
|
|
||||||
currentKey.value++
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -106,11 +114,7 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
filterParams,
|
filterParams,
|
||||||
() => {
|
() => {
|
||||||
// 重置数据
|
resetData()
|
||||||
dataList.value = []
|
|
||||||
page.value = 1
|
|
||||||
isRefreshed.value = false
|
|
||||||
currentKey.value++
|
|
||||||
},
|
},
|
||||||
{ deep: true },
|
{ deep: true },
|
||||||
)
|
)
|
||||||
@@ -125,6 +129,10 @@ const isRefreshed = ref(false)
|
|||||||
const dataList = ref<SubscribeShare[]>([])
|
const dataList = ref<SubscribeShare[]>([])
|
||||||
const currData = ref<SubscribeShare[]>([])
|
const currData = ref<SubscribeShare[]>([])
|
||||||
|
|
||||||
|
useKeepAliveRefresh(resetData, {
|
||||||
|
active: computed(() => props.active),
|
||||||
|
})
|
||||||
|
|
||||||
// 拼装参数
|
// 拼装参数
|
||||||
function getParams() {
|
function getParams() {
|
||||||
let params: { [key: string]: any } = {
|
let params: { [key: string]: any } = {
|
||||||
|
|||||||
Reference in New Issue
Block a user