Vue Router中从详情页返回列表页时如何保留搜索关键词与分页信息
Vue Router 详情页返回列表页保留搜索与分页状态的实现方案
1. 路由参数同步(推荐方案)
把搜索关键词、页码等状态挂载到路由的query参数上,跳转详情页后返回时,路由会自动携带这些参数,列表页直接读取即可恢复状态。
实现代码(列表页)
<script setup> import { useRoute, useRouter } from 'vue-router' import { ref, onMounted } from 'vue' const route = useRoute() const router = useRouter() // 定义搜索与分页状态 const searchForm = ref({ memberName: '' }) const pagination = ref({ currentPage: 1, pageSize: 10 }) // 页面初始化时,从路由query读取参数 onMounted(() => { // 恢复搜索关键词 if (route.query.memberName) { searchForm.value.memberName = route.query.memberName } // 恢复页码 if (route.query.page) { pagination.value.currentPage = parseInt(route.query.page) } // 加载列表数据 fetchList() }) // 搜索操作:重置页码并更新路由 const handleSearch = () => { pagination.value.currentPage = 1 updateRouteQuery() fetchList() } // 分页切换:更新路由 const handlePageChange = (newPage) => { pagination.value.currentPage = newPage updateRouteQuery() fetchList() } // 统一更新路由query的工具函数 const updateRouteQuery = () => { router.push({ query: { ...route.query, // 保留其他可能的query参数 // 为空时不携带该参数,避免url冗余 memberName: searchForm.value.memberName || undefined, page: pagination.value.currentPage || undefined } }) } // 模拟列表数据请求 const fetchList = () => { console.log('当前请求参数:', { memberName: searchForm.value.memberName, page: pagination.value.currentPage, pageSize: pagination.value.pageSize }) // 这里替换成实际的接口请求逻辑 } </script>
详情页跳转时直接用router.push('/detail/123')即可,返回时(浏览器返回按钮或router.back())会回到带有query参数的列表页,自动恢复搜索和分页状态。
2. 状态管理工具(Pinia/Vuex)
如果是多组件共享状态的复杂应用,用状态管理工具统一维护搜索和分页信息,配合持久化插件还能实现页面刷新后保留状态。
Pinia Store 定义
// stores/listState.js import { defineStore } from 'pinia' export const useListStateStore = defineStore('listState', { state: () => ({ searchParams: { memberName: '' }, pagination: { currentPage: 1, pageSize: 10 } }), actions: { // 更新搜索参数 setSearchParams(params) { this.searchParams = { ...this.searchParams, ...params } }, // 更新分页信息 setPagination(pagination) { this.pagination = { ...this.pagination, ...pagination } }, // 重置状态 resetListState() { this.searchParams = { memberName: '' } this.pagination = { currentPage: 1, pageSize: 10 } } }, // 开启持久化,页面刷新不丢失状态 persist: true })
列表页使用
<script setup> import { useListStateStore } from '@/stores/listState' import { onMounted } from 'vue' const listStore = useListStateStore() onMounted(() => { // 初始化加载数据 fetchList() }) const handleSearch = () => { listStore.setSearchParams({ memberName: searchForm.value.memberName }) listStore.setPagination({ currentPage: 1 }) fetchList() } const handlePageChange = (newPage) => { listStore.setPagination({ currentPage: newPage }) fetchList() } const fetchList = () => { console.log('当前请求参数:', { ...listStore.searchParams, ...listStore.pagination }) // 实际接口请求逻辑 } </script>
3. 本地存储缓存(sessionStorage)
简单场景下可以用sessionStorage临时保存状态,适合不需要跨页面共享、仅需返回时保留的场景。
实现代码(列表页)
<script setup> import { ref, onMounted } from 'vue' import { onBeforeRouteLeave } from 'vue-router' const searchForm = ref({ memberName: '' }) const pagination = ref({ currentPage: 1, pageSize: 10 }) // 存储键名 const STORAGE_KEY = 'MEMBER_LIST_STATE' // 页面初始化时读取缓存 onMounted(() => { const savedState = sessionStorage.getItem(STORAGE_KEY) if (savedState) { const { searchParams, currentPage } = JSON.parse(savedState) searchForm.value = searchParams pagination.value.currentPage = currentPage } fetchList() }) // 跳转到详情页前保存状态 onBeforeRouteLeave((to) => { if (to.path.startsWith('/detail')) { sessionStorage.setItem(STORAGE_KEY, JSON.stringify({ searchParams: searchForm.value, currentPage: pagination.value.currentPage })) } }) // 搜索和分页变化时也可实时保存 const handleSearch = () => { pagination.value.currentPage = 1 saveState() fetchList() } const handlePageChange = (newPage) => { pagination.value.currentPage = newPage saveState() fetchList() } const saveState = () => { sessionStorage.setItem(STORAGE_KEY, JSON.stringify({ searchParams: searchForm.value, currentPage: pagination.value.currentPage })) } const fetchList = () => { console.log('当前请求参数:', { memberName: searchForm.value.memberName, page: pagination.value.currentPage }) } </script>
内容的提问来源于stack exchange,提问作者김진석
相关产品推荐
相关产品推荐

