SPA 路由记忆

SPA 路由记忆

名词解释

在中后台系统开发中,访问任何页面时,认证是永远绕不过的槛。以登陆为例,若是检测出当前用户未登陆,会强制跳转到登陆页面提示用户进行登陆。登陆完成后,系统须要跳转至用户原先想访问的页面。这个过程,暂且称之为路由记忆,前面例子中的登陆页面称之为记忆节点node

解决方案

由前面的例子咱们不可贵出路由记忆的关键逻辑:函数

  • 进入记忆节点时记录目标页面
  • 离开记忆节点时跳往目标页面(若是存在)
// 目标页面
const target = undefined;

但如此只能知足存在一个记忆节点的应用,而实际开发中,咱们可能须要多个记忆节点。当应用中存在多个记忆节点时,问题就会慢慢的浮现。this

接下来,咱们对上面的方案进行扩展。prototype

记忆节点集合

首先,咱们须要维护一个记忆节点的集合:code

// 记忆节点集合
const nodes = [];

上次访问记录

在这以前咱们得先思考一个问题:由记忆节点跳往记忆节点时,是否须要触发路由记忆?路由

固然不须要!!!开发

当进入记忆节点时,咱们首先得判断上一个访问页面是否为记忆节点,是则忽略,不然记录目标页面。get

在这以前,咱们须要定义一个变量用来记录上次访问页面,这个变量仅记录上次访问页面便可,不管是否为记忆节点:string

// 上次访问页面
const previous = undefined;

记录目标页面

为保证路由记忆结果的质量,咱们须要对每次路由跳转结束进行监控(不论成功、取消或者失败)。io

结合前面的例子,咱们如今不可贵出,只有在常规页面进入记忆节点时,须要对目标页面进行记录。

/**
 * @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);
    }
}
相关文章
相关标签/搜索