读魔改路由模块源码
孙泽辉 Lv5

做列表+详情页的时候总感觉体验不太如意,想要实现“进入列表时刷新,从列表进入详情时保存列表滚动位置,并在返回时还原位置”,今天偶然看到群友写的模块,让我思维打开了。

问题背景

之前遇到的问题:

列表页 跳到 编辑页,编辑完了返回,发现列表页数据没变化,是因为列表页加了keepalive

后来在 列表页 添加了onActivated时刷新数据,现在确实返回列表后能更新了,但是这同时把整个列表清空重新加载了。这时记录列表页进入详情页之前的scroll位置的插件(vue-scroll-behavior)就失效了,因为数据加载需要时间,而滚动是返回后立即滚动的。

或者更简单的,将列表页 keepalive 关掉,实际上和上面情况一样,也是重新刷新页面。

这个就是最终效果:前进刷新后退不刷新

实现原理

仓库地址:JoeshuTT/vue-page-stack-router: 一个 Vue.js 的页面栈路由管理器 (github.com)

闲话不多讲,看看代码

1
2
3
4
5
// index.js
export * from "./injectionSymbols";
export * from "./useApi";

export { createPageStackRouter } from "./pageStackRouter";

index.js中导出createPageStackRouter函数,看看里面咋写的

代码不贴了,讲讲思路算了

  • install 中,在afterEach中注册跳转逻辑
  • 如果该路由是keep-alive(默认都是),计算当前路由和上一个路由的position差值,position代表位于页面栈的位置,越靠前越大。
  • 根据差值判断pop还是push,如果push则记录当前滚动位置,如果pop则还原滚动位置,并根据路由操作维护一个pageStackList

其中路由router-view组件被替换成了插件中的PageStackRouterView,该组件包装了一层router-view,并根据模块维护的pageStackList来区分是否缓存组件

其实现后退还原位置,而进入刷新页面的方法是:

直接判断当前路由是否属于pageStackList中,如果是,则说明该操作是返回页面,则缓存并还原滚动位置;如果不属于,则说明是进入新页面,不缓存直接刷新走onMounted

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<template>
<router-view v-slot="{ Component, route }">
<keep-alive :include="cachedViews">
<component :is="Component" :key="route.fullPath" />
</keep-alive>
</router-view>
</template>

<script>
import { computed } from "vue";
import { usePageStackList } from "../useApi";

export default {
name: "PageStackRouterView",
setup() {
// 取出当前维护的路由栈
const pageStackList = usePageStackList();
const cachedViews = computed(() => pageStackList.map((v) => v.name));

return {
pageStackList,
cachedViews,
};
},
};
</script>
 Comments
Comment plugin failed to load
Loading comment plugin
Powered by Hexo & Theme Keep
Total words 85.5k