react導航守衛=>路由攔截與重定向


目前網上已知的方法

// 現在是解決這個問題的第二天早上,所以我用了一天的時間,研究這個。特此發出,希望各位可以避免
// 本篇有抽臉的嫌疑,不過我只是陳述與點評,請不要妄加評斷。若無法接受請評論或私聊,我會刪除引用的。
// -過兩天可能會把react的完成版架構放出,to be continued。

  1. 方法說明: 在browerRouter中建立監聽
    摘自: https://juejin.cn/post/6989182520495439880#heading-5

正面的方法

可以使用其做用戶習慣監聽等, 目前在我的代碼中其可以獲取到Redux數據

無法解決的問題(解決辦法不符合規范)

brwerRouter中無法獲取到history, 即無法使用history.push
- 即:無法做到重定向路由。

  1. 方法說明:在 Router/index 中使用 <Redirect to={path}>實現路由的遲滯與重定向
    摘自:https://blog.csdn.net/lllomh/article/details/106768929

正面

該代碼有解決實際問題

無法解決的問題(解決辦法不符合規范)

可能由於其路由使用的是動態重做的,而本代碼是使用邏輯遞歸配置和嵌套路由的吧,
- 當history.back()時無法與TabBar做到良好的相應
- 我還沒直接使用其代碼,這邊並不知道在使用keepalive情況下還是否好用。
- 即:該解決辦法解決了實際問題,但需要本代碼更改和重新嘗試的過多

目前使用的方法

也許不是復雜的才是好的,非暴力不合作
說明:劫持history.push方法

let history = this.props.history;
let _hpush = history.push;
history.push = function (path, state) {
    console.log("onPath", this.props, path, state);
    // 添加邏輯路由判斷
    _hpush.call(history, path, state)
}.bind(this)

2021/12/24修改版 優化版劫持並與路由key合並,使其參與系統中修改

  1. 如果可以的話, 我這邊有什么寫的可以改進的請留言
  2. 該文件為<核心架構邏輯=>路由跳轉規則部分>,當前項目架構完成(部分待優化)
  3. 文件中使用的加載僅為個人使用

Routes/index 中注冊路由劫持方法

// 劫持 history.push 方法,運行之前執行路由校驗
let history = this.props.history;
let _hpush = history.push;
history.push = function (path, state) {
    let route = Router_rule(history.location, path, this.props)
    if (route) {
        path = typeof route === 'boolean' ? path : route;

        _hpush.call(history, path, state);
    }
}.bind(this)

src\Routes\rule.ts
屬於半核心層了吧,沒啥可不能放的

// 在antd-m 中看到發現好用並使用
import _ from 'lodash';
// 本項目中控制路由名稱和路由配置表的文件
import { RouteNick } from "./config";
import { Toast } from 'antd-mobile';
// redux 項目
import { initAuth } from 'Store/auth/actions';


let SESSIONKEY_AUTH = "KEY_AUTH";

export interface router_rule {
    prev: string;
    next: string;
    props: any;
}
export interface linkto {
    pathname: string,
    state?: {
        [key: string]: any;
    }
}

/**
 * @param this TS使用的this,需要注冊
 * @param prev 當前路由地址
 * @param next 點擊路由地址
 * @param props 公共的props函數
 * @returns 
 */
function Router_rule(this: any, prev: linkto, next: linkto | string, props: any): boolean | linkto {
    // 整理結構 保證返回
    next = path_check(next);

    // 若路由重復點擊則不做處理
    if (prev.pathname === next.pathname)
        return false;
    // 存在路由規則 則處理 否則 直接允許跳轉
    else if (this[next.pathname])
        return this[next.pathname](prev, next, props);
    else
        return true;
}

const rules = {
    // TODO: demo ========================================== start
    // [RouteNick.{demo}]: function (this: any, prev: linkto, next: linkto, props: any): boolean | linkto {
    //     if (props.Store.getState().auth?.token)
    //         return true;
    //     else {
    //         Toast.show("登錄后即可查看賬戶信息");
    //         return path_check(RouteNick.ROUTE_LOGIN);
    //     }
    // },

    // TODO: demo ========================================== end

    [RouteNick.ROUTE_MINE]: function (this: any, prev: linkto, next: linkto, props: any): boolean | linkto {
        let session_auth = sessionStorage.getItem(SESSIONKEY_AUTH);
        let redux_auth = props.Store.getState().auth;
        
        if (!_.isEmpty(redux_auth.userInfo)) {
            sessionStorage.setItem(SESSIONKEY_AUTH, JSON.stringify(redux_auth));
            return true;
        }
        else if(session_auth && session_auth !== '{}') {
            let auth = JSON.parse(session_auth);
            props.Store.dispatch(initAuth(auth));
            return true;
        }
        else {
            Toast.show("登錄后即可查看賬戶信息");
            return path_check(RouteNick.ROUTE_LOGIN);
        }
    }
}

let path_check = (path: linkto | string): linkto => {
    if (typeof path === 'string')
        return { pathname: path }

    return path
}

export default Router_rule.bind(rules);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM