在某些情况下,可以方便地参考用户访问的最后一条路线。 例如,假设我们正在处理一个多步骤表单,并且用户从一个步骤进行到下一个步骤。 拥有上一步的路线是理想的,这样我们可以知道用户离开的地方,以防他们导航离开并稍后返回以完成表单。
我们将介绍如何存储最后一条已知路线,然后在需要时取回它。 在本示例中,我们将在Vue中工作,并将vue-router用于路由,将localStorage用于保留有关上次访问路由的信息。
这是我们将使用的示例:
首先,让我们概述一下路线结构
我们的示例共有三条路线:
-
/home
-
/hello
-
/goodbye
每个路由都需要分配一个name属性,因此我们将其添加到router.js文件中:
// router.js
import Vue from "vue";
import Router from "vue-router";
import Hello from "@/components/Hello";
import Goodbye from "@/components/Goodbye";
import {
HELLO_URL,
GOODBYE_URL
} from "@/consts";
Vue.use(Router);
const router = new Router({
mode: "history",
routes: [
{ path: "/", name: "home" },
{ path: HELLO_URL, name: "hello", component: Hello },
{ path: GOODBYE_URL, name: "goodbye", component: Goodbye }
]
});
export default router;
接下来,让我们看一下需求
我们知道第一个要求是将最后访问的路由存储在localStorage
。 其次,我们需要能够检索它。 但是,应该在什么条件下获取和应用路由? 这给了我们两个额外的要求。
- 用户输入主要路线(
/home
),导航离开它,然后想返回它。 - 用户在特定时间段内处于非活动状态,会话期满,并且我们希望用户重新启动会话后回到上一次显示的屏幕。
为了进行重定向,我们需要满足这四个要求。
现在,让我们进入代码。
要求1:将最后一个路由名称保存在localStorage中
我们想在localStorage
保留对上次访问路由的引用。 例如,如果用户在/checkout
然后离开该站点,那么我们要保存该站点,以便以后可以完成购买。
为此,我们要在用户输入任何新路线时保存路线名称。 我们将使用一个名为afterEach
的导航保护 ,该导航保护在每次路线转换完成时都会触发。 它提供一个to
对象,它是目标Route Object 。 在该挂钩中,我们可以提取该路由的名称,并使用setItem
方法将其保存在localStorage
。
// router.js
const router = new Router( ... );
router.afterEach(to => {
localStorage.setItem(LS_ROUTE_KEY, to.name);
});
...
export default router;
要求2:从localStorage获取最后一个路由名称并重定向
现在已经保存了最后一条路线的名称,我们需要能够获取它并在需要时触发重定向。 我们想在输入新路线之前检查是否应该重定向,因此我们将使用另一个名为beforeEach
导航保护。 这个卫兵收到三个论点:
-
to
:目标路线对象 -
from
:当前路线从 -
next
:必须在守护程序中调用以解决钩子的函数
在这种保护下,我们使用localStorage.getItem()
方法读取了最后访问的路由的名称。 然后,我们确定是否应重定向用户。 此时,我们检查目标路由( to
)是我们的主路由( /home
),以及是否确实在localStorage
有最后一条路由。
如果满足这些条件,我们将触发包含最后访问路线名称的next
方法。 反过来,这将触发重定向到该路由。
如果任何条件失败,那么我们将next
不带任何参数的情况下触发next
。 这会将用户移至管道中的下一个挂钩,并继续进行常规路由而无需重定向。
// router.js
const router = new Router( ... );
router.beforeEach((to, from, next) => {
const lastRouteName = localStorage.getItem(LS_ROUTE_KEY);
const shouldRedirect = Boolean(
to.name === "home" &&
lastRouteName
);
if (shouldRedirect) next({ name: lastRouteName });
else next();
});
...
export default router;
这涵盖了四个需求中的两个! 让我们继续第三个要求。
要求3:初次访问条件
现在,我们需要检查用户是第一次访问主要路线(来自其他来源)还是从应用程序中的另一条路线导航。 为此,我们可以添加一个标记,该标记在创建路由器时设置为true,并在首次转换完成后将其设置为false。
// router.js
const router = new Router( ... );
let isFirstTransition = true;
router.beforeEach((to, from, next) => {
const lastRouteName = localStorage.getItem(LS_ROUTE_KEY);
const shouldRedirect = Boolean(
to.name === "home" &&
&& lastRouteName
&& isFirstTransition
);
if (shouldRedirect) next({ name: lastRouteName });
else next();
isFirstTransition = false;
});
...
export default router;
好的,我们还需要满足另一个要求:如果用户在特定时间段内处于非活动状态的时间更长,我们希望将用户重定向到最后一条已知路由。
要求4:活动时间条件
同样,我们将使用localStorage
保留有关用户的最后访问路线的信息。
在beforeEach
防护中,我们将从localStorage
获取路由,并检查从那一刻起经过的时间是否在我们的阈值(由hasBeenActiveRecently
定义)内。 然后,在我们的shouldRedirect
,我们将确定是否应该进行路由重定向。
我们还需要保存该信息,我们将在afterEach
中进行此afterEach
。
// router.js
const router = new Router( ... );
let isFirstTransition = true;
router.beforeEach((to, from, next) => {
const lastRouteName = localStorage.getItem(LS_ROUTE_KEY);
const lastActivityAt = localStorage.getItem(LS_LAST_ACTIVITY_AT_KEY);
const hasBeenActiveRecently = Boolean(
lastActivityAt && Date.now() - Number(lastActivityAt) < MAX_TIME_TO_RETURN
);
const shouldRedirect = Boolean(
to.name === "home" &&
&& lastRouteName
&& isFirstTransition
&& hasBeenActiveRecently
);
if (shouldRedirect) next({ name: lastRouteName });
else next();
isFirstTransition = false;
});
router.afterEach(to => {
localStorage.setItem(LS_ROUTE_KEY, to.name);
localStorage.setItem(LS_LAST_ACTIVITY_AT_KEY, Date.now());
});
...
export default router;
我们符合要求!
而已! 我们满足了所有四个要求,即:
- 我们将最后访问的路线存储在
localStorage
- 我们有一种方法可以从
localStorage
检索上次访问的路线 - 如果用户初次访问应用程序时,我们会将其重定向回主要路线
- 我们为用户提供在特定时间段内的最新已知路线的重定向
当然,我们可以通过为应用程序增加更多的复杂性以及为shouldRedirect
变量增加新的条件来进一步扩展此方法,但这比我们需要了解如何保持上次访问的路由持久并在需要时检索它要多得多。
翻译自: https://css-tricks.com/storing-and-using-the-last-known-route-in-vue/