路由缓存问题

使用带有参数的路由需要注意的是,当用户从/users/id1导航到/users/id2时,相同的组件实例将被重复使用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会被调用。

如何解决问题?

思路1:让组件实例不再复用,强制销毁重建;

思路2:监听路由变化,变化之后执行数据更新操作;

方案一:给router-view添加key

以当前路由完整路径为key的值,给router-view组件绑定

为什么用key?我们最常见的用例是与v-for结合,但是key也可以用于强制替换一个元素/组件而不是复用它。

  • 在适当的时候触发组件的生命周期钩子
  • 触发过渡
1
<RouterView :key="$route.fullPath" />

但是这种方法也存在问题,过于粗暴,如果每次导航都销毁组件重建,说明每次导航都要重新发送一次数据请求,如果有相同数据,则存在浪费。那怎么做到只发送需要的数据请求呢?

方案二:使用beforeRouterUpdate导航钩子

该钩子函数可以在每次路由更新之前执行,在回调中执行需要数据更新的业务逻辑即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { onBeforeRouteUpdate, useRoute } from "vue-router";
const route = useRoute();
const getCategory = async (id = route.params.id) => {
// 如何在setup中获取路由参数 useRoute() -> route 等价于this.$route
const res = await getTopCategoryAPI(id);
categoryData.value = res.result;
};
onMounted(() => getCategory());

//目标:路由参数变化的时候,可以把分类数据接口重新发送
onBeforeRouteUpdate((to) => {
console.log(to);
getCategory(to.params.id);
});

useRoute 用于在 Vue 3 中访问当前路由对象。它返回一个包含当前路由信息的对象,类似于 this.$route 在 Vue 2 中的用法。它返回一个响应式的路由对象,包含了当前路由的各种信息,例如 pathparamsquery ,这里是使用当前路由对象的params的id。

在 Vue Router 中,onBeforeRouteUpdate 是一个导航守卫,它会在当前路由更新但是同一组件被复用时被调用。这个守卫的回调函数接受一个 to 参数,它表示即将导航到的目标路由对象。

其中 to.params.id 表示即将导航到的路由的 id 参数