88 :activeKey =" activeKey"
99 :filters =" props.classList?.filters || {}"
1010 :selectedFilters =" selectedFilters"
11+ :filterVisible =" filterVisible"
1112 :specialCategoryState =" props.specialCategoryState"
1213 @tab-change =" handleTabChange"
1314 @open-category-modal =" openCategoryModal"
1415 @toggle-filter =" handleToggleFilter"
1516 @reset-filters =" handleResetFilters"
17+ @filter-visible-change =" handleFilterVisibleChange"
1618 @close-special-category =" () => emit('close-special-category')"
1719 />
1820
@@ -143,6 +145,7 @@ import { usePaginationStore } from '@/stores/paginationStore';
143145import { getCategoryData } from ' @/api/modules/module' ;
144146import { processExtendParam } from ' @/utils/apiUtils' ;
145147import { encodeFilters } from ' @/api/utils' ;
148+ import { useRouter } from ' vue-router' ;
146149import CategoryNavigation from ' ./CategoryNavigation.vue' ;
147150import FilterSection from ' ./FilterSection.vue' ;
148151import VideoGrid from ' ./VideoGrid.vue' ;
@@ -207,6 +210,8 @@ const props = defineProps({
207210
208211const emit = defineEmits ([' activeKeyChange' , ' special-action' , ' close-special-category' , ' folder-navigate' ]);
209212
213+ const router = useRouter ();
214+
210215// 使用翻页统计store
211216const paginationStore = usePaginationStore ();
212217
@@ -261,6 +266,69 @@ const selectedFilters = reactive({});
261266const categoryModalVisible = ref (false );
262267const videoGridRef = ref (null );
263268
269+ // 筛选条件和展开状态持久化函数
270+ const saveFiltersToUrl = () => {
271+ const currentQuery = { ... router .currentRoute .value .query };
272+
273+ if (Object .keys (selectedFilters).length > 0 ) {
274+ // 将筛选条件编码为JSON字符串保存到URL
275+ currentQuery .filters = JSON .stringify (selectedFilters);
276+ } else {
277+ // 如果没有筛选条件,删除URL中的filters参数
278+ delete currentQuery .filters ;
279+ }
280+
281+ // 保存筛选展开状态
282+ if (Object .keys (filterVisible).length > 0 ) {
283+ currentQuery .filterVisible = JSON .stringify (filterVisible);
284+ } else {
285+ delete currentQuery .filterVisible ;
286+ }
287+
288+ // 更新URL,但不触发页面刷新
289+ router .replace ({
290+ query: currentQuery
291+ }).catch (() => {
292+ // 忽略导航重复错误
293+ });
294+ };
295+
296+ // 从URL恢复筛选条件和展开状态
297+ const restoreFiltersFromUrl = () => {
298+ const urlFilters = router .currentRoute .value .query .filters ;
299+ const urlFilterVisible = router .currentRoute .value .query .filterVisible ;
300+
301+ // 恢复筛选条件
302+ if (urlFilters) {
303+ try {
304+ const parsedFilters = JSON .parse (urlFilters);
305+ // 清空现有筛选条件
306+ Object .keys (selectedFilters).forEach (key => {
307+ delete selectedFilters[key];
308+ });
309+ // 恢复筛选条件
310+ Object .assign (selectedFilters, parsedFilters);
311+ } catch (error) {
312+ console .error (' 解析URL中的筛选条件失败:' , error);
313+ }
314+ }
315+
316+ // 恢复筛选展开状态
317+ if (urlFilterVisible) {
318+ try {
319+ const parsedFilterVisible = JSON .parse (urlFilterVisible);
320+ // 清空现有展开状态
321+ Object .keys (filterVisible).forEach (key => {
322+ delete filterVisible[key];
323+ });
324+ // 恢复展开状态
325+ Object .assign (filterVisible, parsedFilterVisible);
326+ } catch (error) {
327+ console .error (' 解析URL中的筛选展开状态失败:' , error);
328+ }
329+ }
330+ };
331+
264332// 目录模式翻页状态管理
265333const folderPageData = reactive ({});
266334const folderLoadingMore = reactive ({});
@@ -358,6 +426,9 @@ const toggleFilter = (filterKey, filterValue, filterName) => {
358426 selectedFilters[activeKey .value ][filterKey] = filterValue;
359427 }
360428
429+ // 保存筛选条件到URL
430+ saveFiltersToUrl ();
431+
361432 // 如果在目录模式下,重新获取目录数据
362433 if (folderIsActive .value && folderCurrentBreadcrumb .value ) {
363434 handleFolderNavigate (folderCurrentBreadcrumb .value );
@@ -370,6 +441,9 @@ const toggleFilter = (filterKey, filterValue, filterName) => {
370441const resetFilters = (categoryId ) => {
371442 delete selectedFilters[categoryId];
372443
444+ // 保存筛选条件到URL
445+ saveFiltersToUrl ();
446+
373447 // 如果在目录模式下,重新获取目录数据
374448 if (folderIsActive .value && folderCurrentBreadcrumb .value ) {
375449 handleFolderNavigate (folderCurrentBreadcrumb .value );
@@ -673,6 +747,13 @@ const handleToggleFilter = (data) => {
673747 toggleFilter (filterKey, filterValue, filterName);
674748};
675749
750+ const handleFilterVisibleChange = (data ) => {
751+ const { categoryId , visible } = data;
752+ filterVisible[categoryId] = visible;
753+ // 保存筛选展开状态到URL
754+ saveFiltersToUrl ();
755+ };
756+
676757const handleResetFilters = () => {
677758 resetFilters (activeKey .value );
678759};
@@ -721,6 +802,7 @@ watch(() => props.recommendVideos, (newVideos) => {
721802}, { immediate: true });
722803
723804// 添加classList watch的防护变量
805+ // 防止递归更新的标志
724806let isClassListUpdating = false ;
725807let lastClassListHash = ' ' ;
726808
@@ -755,8 +837,13 @@ watch(() => props.classList, (newClassList, oldClassList) => {
755837 lastClassListHash = newHash;
756838
757839 try {
758- if (newClassList !== oldClassList) {
759- console .log (' 🗂️ [DEBUG] classList发生变化,清除筛选状态' );
840+ // 检查URL中是否有筛选参数需要恢复
841+ const currentQuery = router .currentRoute .value .query ;
842+ const hasFiltersInUrl = currentQuery .filters || currentQuery .filterVisible ;
843+
844+ // 只有在classList真正发生变化且URL中没有筛选参数时才清除筛选状态
845+ if (newClassList !== oldClassList && ! hasFiltersInUrl) {
846+ console .log (' 🗂️ [DEBUG] classList发生变化且URL中无筛选参数,清除筛选状态' );
760847 // 清除筛选状态
761848 Object .keys (selectedFilters).forEach (key => {
762849 delete selectedFilters[key];
@@ -765,6 +852,8 @@ watch(() => props.classList, (newClassList, oldClassList) => {
765852 delete filterVisible[key];
766853 });
767854 console .log (' 🗂️ [DEBUG] 筛选状态已清除' );
855+ } else if (hasFiltersInUrl) {
856+ console .log (' 🗂️ [DEBUG] URL中有筛选参数,跳过筛选状态清除' );
768857 }
769858
770859 // 如果当前处于folder模式,不要重置activeKey,避免覆盖folder状态
@@ -811,15 +900,22 @@ watch(() => props.sourceRoute?.query?.activeKey, (newActiveKey) => {
811900 }
812901}, { immediate: true });
813902
814- onMounted (() => {
903+ onMounted (async () => {
904+ // 从URL恢复筛选条件
905+ restoreFiltersFromUrl ();
906+
815907 // 优先使用父组件传递的activeKey,如果没有则使用默认值
816908 const parentActiveKey = props .sourceRoute ? .query ? .activeKey ;
817909 const targetActiveKey = parentActiveKey || getDefaultActiveKey ();
818910
819- console . log ( ' [DEBUG] VideoList onMounted - parentActiveKey: ' , parentActiveKey, ' targetActiveKey: ' , targetActiveKey);
820-
911+ // 使用nextTick确保筛选状态已经传递给子组件
912+ await nextTick ();
821913 activeKey .value = targetActiveKey;
822914
915+ // 再次使用nextTick确保classList watcher执行完毕后,重新恢复筛选状态
916+ await nextTick ();
917+ restoreFiltersFromUrl ();
918+
823919 // 对于推荐分类,确保loading状态正确
824920 if (targetActiveKey === " recommendTuijian404" ) {
825921 loadingCategory[targetActiveKey] = false ;
@@ -828,7 +924,6 @@ onMounted(() => {
828924 listData[targetActiveKey] = [... props .recommendVideos ];
829925 pageData[targetActiveKey] = { page: 1 , hasNext: false };
830926 loadingMore[targetActiveKey] = false ;
831- console .log (' [DEBUG] 推荐数据已设置,跳过getListData调用' );
832927 } else {
833928 // 如果没有推荐数据,才调用getListData
834929 getListData (activeKey .value );
0 commit comments