本文介绍在Vue3项目中,当通过router.push或replace更新URL的query参数(如id)时,页面数据未自动刷新的常见问题。核心解决方案是为App.vue中的router-view添加动态key属性,使其随路由路径变化而重新渲染。此外,针对使用keep-alive缓存组件的场景,提供了通过provide/inject结合v-if控制组件显隐的进阶刷新方案。
一、业务场景
在列表页携带特定id跳转至详情页后,若详情页的id发生变更,需要重新加载当前页面的数据。
此跳转逻辑主要涉及两种场景:假设A页面展示的是id为1111的详情页,而B页面展示的是id为2222的详情页。
- 第一种场景:用户从A页面跳转至B页面,随后从B页面返回时,直接回到列表页。
- 第二种场景:用户从A页面跳转至B页面,从B页面返回时先回到A页面,随后从A页面再次返回至列表页。
二、实现方式
实现该功能的核心方法依赖于Vue Router提供的$router.push和$router.replace。
针对从A页面跳转至B页面的操作,具体实现如下:
- 对于第一种场景:
import { useRouter } from 'vue-router'
const router = useRouter()
router.replace({
path: '/eFileManagement/company/collection/detail',
query: { id: '2222' }
})- 对于第二种场景:
import { useRouter } from 'vue-router'
const router = useRouter()
router.push({
path: '/eFileManagement/company/collection/detail',
query: { id: '2222' }
})三、发现问题
完成上述步骤后,虽然所需功能看似已实现,但会观察到地址栏中的id确实发生了变化,然而页面数据并未随之刷新。此时,只需在App.vue中的router-view标签上添加一个动态的key值即可解决该问题。
具体配置如下:
<router-view :key="routerKey"></router-view>import { useRoute } from 'vue-router'
const route = useRoute()
const routerKey = computed(() => {
return route.path + Math.random()
})完成上述配置后,问题即可解决。
延伸:(keep-alive)
如果router-view被包裹在keep-alive标签内,则需要额外给router-view添加一个状态值,用于控制其显示与隐藏,并通过provide注入该状态,以便在页面中调用。
App.vue中的配置如下:
<router-view :key="routerKey" v-if="isAlive"></router-view>import { ref, provide, nextTick } from 'vue'
const isAlive = ref<boolean>(true)
function reload() {
isAlive.value = false
nextTick(() => {
isAlive.value = true
})
}
provide('reload', reload)在A页面中的配置如下:
import { inject } from 'vue'
const reload:any = inject('reload')随后,在调用push或replace方法之后,需执行reload方法。
import { useRouter } from 'vue-router'
const router = useRouter()
router.push({
path: '/eFileManagement/company/collection/detail',
query: { id: '2222' }
})
reload()总结
以上为个人经验分享,希望能为大家提供参考,也希望大家多多支持本站。