SPA 路由影象
名词解释
在中背景体系开辟中,接见任何页面时,认证是永久绕不过的槛。以登录为例,假如检测出当前用户未登录,会强迫跳转到登录页面提醒用户举行登录。登录完成后,体系须要跳转至用户原先想接见的页面。这个历程,临时称之为路由影象,前面例子中的登录页面称之为影象节点。
解决计划
由前面的例子我们不难得出路由影象的症结逻辑:
- 进入影象节点时纪录目的页面
- 脱离影象节点时跳往目的页面(假如存在)
// 目的页面
const target = undefined;
但云云只能满足存在一个影象节点的运用,而现实开辟中,我们能够须要多个影象节点。当运用中存在多个影象节点时,题目就会逐步的显现。
接下来,我们对上面的计划举行扩大。
影象节点鸠合
起首,我们须要保护一个影象节点的鸠合:
// 影象节点鸠合
const nodes = [];
上次接见纪录
在这之前我们得先思索一个题目:由影象节点跳往影象节点时,是不是须要触发路由影象?
固然不须要!!!
当进入影象节点时,我们起首得推断上一个接见页面是不是为影象节点,是则疏忽,不然纪录目的页面。
在这之前,我们须要定义一个变量用来纪录上次接见页面,这个变量仅纪录上次接见页面即可,不管是不是为影象节点:
// 上次接见页面
const previous = undefined;
纪录目的页面
为保证路由影象效果的质量,我们须要对每次路由跳转完毕举行监控(不管胜利、作废或许失利)。
连系前面的例子,我们如今不难得出,只要在通例页面进入影象节点时,须要对目的页面举行纪录。
/**
* @param to {string} 去往页面
*/
function mark (to) {
// 备份上次接见页面,防备被覆写
const backup = previous;
// 纪录上次接见页面
previous = to;
// 假如上一个接见页面是影象节点,中缀函数
if (~nodes.indexOf(backup)) return;
// 假如去往页面不是影象节点,中缀函数
if (!~nodes.indexOf(to)) return;
// 纪录目的页面
target = backup;
}
跳往目的页面
在每次路由跳转之前,我们须要检测是不是是影象节点进入通例页面且是不是存在目的页面纪录,假如前提都满足,则打断原有操纵跳往目的页面,并清空目的页面纪录。
/**
* @param to {string} 去往页面
*/
function check (to) {
// 若目的页面不存在,中缀函数
if (!target) return;
// 备份目的页面,防备在运用之前被清空
const backup = target;
// 假如去往页面是影象节点,中缀函数
if (~nodes.indexOf(to)) return;
// 假如上次接见不是影象节点,中缀函数
if (!~nodes.indexOf(previous)) return;
// 清空目的纪录
target = undefined;
// 路由跳转,假定实行函数为 navigate
navigate(target);
}
代码整合
ES5
var RouterMemory = function (nodes) {
// 目的页面
this.target = undefined;
// 上次接见页面
this.previous = undefined;
// 影象节点鸠合
this.nodes = nodes && nodes instanceof Array ? nodes : [];
}
/**
* 纪录上次接见及目的页面
* @param to {string} 去往页面
*/
RouterMemory.prototype.mark = function (to) {
// 备份上次接见页面,防备被覆写
var backup = this.previous;
// 纪录上次接见页面
this.previous = to;
// 假如上一个接见页面是影象节点,中缀函数
if (~nodes.indexOf(backup)) return;
// 假如去往页面不是影象节点,中缀函数
if (!~nodes.indexOf(to)) return;
// 纪录目的页面
this.target = backup;
}
/**
* 跳往目的页面
* @param to {string} 去往页面
*/
RouterMemory.prototype.check = function (to) {
// 若目的页面不存在,中缀函数
if (!this.target) return;
// 备份目的页面,防备在运用之前被清空
const backup = this.target;
// 假如去往页面是影象节点,中缀函数
if (~nodes.indexOf(to)) return;
// 假如上次接见不是影象节点,中缀函数
if (!~nodes.indexOf(this.previous)) return;
// 清空目的页面
this.target = undefined;
// 路由跳转,假定实行函数为 navigate
navigate(this.target);
}
ES Next
class RouterMemory {
constructor (nodes) {
// 目的页面
this.target = undefined;
// 上次接见页面
this.previous = undefined;
// 影象节点鸠合
this.nodes = nodes && nodes instanceof Array ? nodes : [];
}
/**
* @param to {string} 去往页面
*/
mark (to) {
// 备份上次接见页面,防备被覆写
const backup = this.previous;
// 纪录上次接见页面
this.previous = to;
// 假如上一个接见页面是影象节点,中缀函数
if (nodes.includes(backup)) return;
// 假如去往页面不是影象节点,中缀函数
if (!nodes.includes(to)) return;
// 纪录目的页面
this.target = backup;
}
/**
* @param to {string} 去往页面
*/
check (to) {
// 若目的页面不存在,中缀函数
if (!this.target) return;
// 备份目的页面,防备在运用之前被清空
const backup = this.target;
// 假如去往页面是影象节点,中缀函数
if (nodes.includes(to)) return;
// 假如上次接见不是影象节点,中缀函数
if (!nodes.includes(this.previous)) return;
// 清空目的纪录
this.target = undefined;
// 路由跳转,假定实行函数为 navigate
navigate(this.target);
}
}