日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

react实现路由跳转拦截功能(导航守卫)

發(fā)布時間:2024/1/8 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 react实现路由跳转拦截功能(导航守卫) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

react實(shí)現(xiàn)路由跳轉(zhuǎn)攔截功能(導(dǎo)航守衛(wèi))

    • 背景
    • 方法1:通過Prompt組件實(shí)現(xiàn)react路由跳轉(zhuǎn)攔截功能
      • Prompt組件介紹
      • Prompt組件示例
      • 自定義Prompt組件的提示彈窗
    • 方法2:通過history.block實(shí)現(xiàn)react路由跳轉(zhuǎn)攔截功能
      • history.block介紹
      • history.block基本示例
      • history.block使用示例(自定義彈窗)
    • 文章參考

背景

最近接到一個需求,當(dāng)用戶將要離開指定頁面的時候,需要攔截頁面的跳轉(zhuǎn),并彈出提示框,提醒用戶去做某一項(xiàng)操作(比如數(shù)據(jù)的保存和提交),只有當(dāng)用戶完成操作之后,或者關(guān)閉提示窗,才能離開此頁面進(jìn)行下一頁面的跳轉(zhuǎn)。
這樣的需求,通常做法是:監(jiān)聽路由的跳轉(zhuǎn)操作,阻塞跳轉(zhuǎn),實(shí)現(xiàn)攔截,并在用戶處理完需要的操作之后(如數(shù)據(jù)保存、提交、關(guān)閉彈窗),才放開跳轉(zhuǎn)權(quán)限,允許用戶跳轉(zhuǎn)下一頁面。

方法1:通過Prompt組件實(shí)現(xiàn)react路由跳轉(zhuǎn)攔截功能

如果前端項(xiàng)目是使用vue來編寫,我們可以很快處理這一問題,因?yàn)関ue自帶的導(dǎo)航守衛(wèi)Api如beforeRouteLeave就可以實(shí)現(xiàn)該功能。

但是react并沒有提供像vue一樣的導(dǎo)航守衛(wèi)Api,因此我們需要另辟蹊徑。react-router-dom提供了Prompt組件,通過在需要進(jìn)行路由跳轉(zhuǎn)攔截的頁面的任意地方加上Prompt組件,我們都能實(shí)現(xiàn)路由跳轉(zhuǎn)攔截。

Prompt組件介紹

<Prompt when={true} message={(location) => { return '信息還沒保存,確定離開嗎?' }} />

Prompt接受兩個屬性:

  • when(非必傳),數(shù)據(jù)類型為boolean值。
    when=true時,阻塞路由跳轉(zhuǎn)(如果message為字符串或者message的方法返回字符串,還會彈出提示彈窗,彈窗信息為message的字符串值或者message方法返回的字符串);
    when=false,不阻塞路由跳轉(zhuǎn),也不彈出提示彈窗(當(dāng)when=false時,即使message為字符串或者message的方法返回字符串,也不會彈出提示窗)。
    注意:只有當(dāng)when=true的時候,才會執(zhí)行message的方法。

  • message(必傳),數(shù)據(jù)類型可以是字符串或方法
    message可以是字符串或方法,如果message為方法,那么該方法會接收一個location參數(shù),參數(shù)包含將要跳轉(zhuǎn)的下一個路由的路徑等信息(如果message為方法,那么該方法主要用于處理路由攔截后的操作)。
    前提是當(dāng)when=true時,message為字符串,則會阻塞路由并彈出提示彈窗,彈窗內(nèi)容為message字符串。
    前提是當(dāng)when=true時,message為方法,當(dāng)方法返回true就順利跳轉(zhuǎn);返回false則阻塞路由跳轉(zhuǎn)(不會彈出提示彈窗);當(dāng)方法返回字符串就阻塞路由跳轉(zhuǎn),并彈出提示彈窗,彈窗提示內(nèi)容為方法返回的字符串。

  • Prompt對路由攔截的作用只會作用于其所掛載的當(dāng)前路由,當(dāng)跳轉(zhuǎn)到另一個路由(或者Prompt組件被銷毀的時候),該P(yáng)rompt組件將不會再對路由跳轉(zhuǎn)有攔截作用,除非重新掛載和初始化Prompt組件

  • Prompt組件示例

    接下來我們看看在react中如何使用Prompt組件實(shí)現(xiàn)路由攔截:
    頁面上任意位置掛載Prompt 組件,點(diǎn)擊“路由跳轉(zhuǎn)”按鈕,觸發(fā)路由跳轉(zhuǎn)事件

    import React, { Component } from 'react'; import { Button } from 'antd'; import { withRouter, Prompt } from 'react-router-dom'; // 從react-router-dom中引出Prompt組件class index extends Component {state = {}// 跳轉(zhuǎn)路由handleRouterSwitch = () => {this.props.history.push('/outside')}render() {return (<div><Button onClick={this.handleRouterSwitch}>跳轉(zhuǎn)路由</Button>{/* 頁面的任何地方加上Prompt組件都生效 */}<Prompt when={true} message="信息還沒保存,確定離開嗎?" /></div>)} }export default withRouter(index)

    接下來我們看看Prompt組件的when和message屬性的不同屬性值,在觸發(fā)路由跳轉(zhuǎn)時,會發(fā)生什么:

    ① 只賦值when屬性,不賦值message屬性,頁面會報錯,提示message屬性應(yīng)必傳

    <Prompt when={true} />


    ② when=true,message為字符串,當(dāng)觸發(fā)路由跳轉(zhuǎn)事件時,路由跳轉(zhuǎn)會被攔截,并彈出提示窗,提示信息為message的值,點(diǎn)擊提示窗確定按鈕,路由被釋放,跳轉(zhuǎn)到指定頁面;點(diǎn)擊取消按鈕,路由跳轉(zhuǎn)被取消,同時關(guān)閉提示窗

    <Prompt when={true} message="信息還沒保存,確定離開嗎?" />


    ③ when=false,message為字符串,當(dāng)觸發(fā)路由跳轉(zhuǎn)事件時,路由跳轉(zhuǎn)不會被攔截,路由會跳轉(zhuǎn)到指定頁面。這是因?yàn)?font color="red">只有當(dāng)when=true的時候,才會執(zhí)行message的方法。

    <Prompt when={false} message="信息還沒保存,確定離開嗎?" />

    ④ when=true,message為方法,且方法返回值為字符串,當(dāng)觸發(fā)路由跳轉(zhuǎn)事件時,路由跳轉(zhuǎn)會被攔截,并彈出提示窗,提示信息為message的方法返回的字符串,點(diǎn)擊提示窗確定按鈕,路由被釋放,跳轉(zhuǎn)到指定頁面;點(diǎn)擊取消按鈕,路由跳轉(zhuǎn)被取消,同時關(guān)閉提示窗

    <Prompt when={true} message={(location) => {return '信息還沒保存,確定離開嗎?'}} />


    ⑤ when=false,message為方法,且方法返回值為字符串,同時message方法內(nèi)還包含如console.log(‘跳轉(zhuǎn)’)語句。當(dāng)觸發(fā)路由跳轉(zhuǎn)事件時,路由跳轉(zhuǎn)不會被攔截,路由會跳轉(zhuǎn)到指定頁面。且message方法未被執(zhí)行。這是因?yàn)?font color="red">只有當(dāng)when=true的時候,才會執(zhí)行message的方法。

    <Prompt when={false} message={(location) => {console.log(location, '跳轉(zhuǎn)');return '信息還沒保存,確定離開嗎?'; }} />

    ⑥ when=true,message為方法,且方法返回值為true,同時message方法內(nèi)還包含如console.log(‘跳轉(zhuǎn)’)語句。當(dāng)觸發(fā)路由跳轉(zhuǎn)事件時,message方法會被執(zhí)行,路由跳轉(zhuǎn)不會被攔截,路由會跳轉(zhuǎn)到指定頁面。

    <Prompt when={true} message={(location) => {console.log(location, '跳轉(zhuǎn)');return true; }} />


    ⑦ when=true,message為方法,且方法返回值為false,同時message方法內(nèi)還包含如console.log(‘跳轉(zhuǎn)’)語句。當(dāng)觸發(fā)路由跳轉(zhuǎn)事件時,message方法會被執(zhí)行,路由跳轉(zhuǎn)會被攔截,但不會彈出提示框。

    <Prompt when={true} message={(location) => {console.log(location, '跳轉(zhuǎn)');return false; }} />


    ⑧ 接下來我們演示一下項(xiàng)目中通過Prompt組件攔截用戶跳轉(zhuǎn)路由。
    需求:

  • 用戶跳轉(zhuǎn)頁面的時候,判斷用戶是否保存了用戶數(shù)據(jù),如果沒有,則阻塞跳轉(zhuǎn),彈出確認(rèn)提示。
  • 用戶跳轉(zhuǎn)頁面的時候,判斷用戶是否是跳轉(zhuǎn)了不讓跳轉(zhuǎn)的特殊頁面,如果沒有,則阻塞跳轉(zhuǎn),彈出確認(rèn)提示。
    做法:
    Prompt的when屬性值變量放于state中,message賦值為方法
    注意:
    當(dāng)when的屬性值,初始化必須為true,否則阻塞不了路由跳轉(zhuǎn)。因?yàn)閟etState是異步操作
  • import React, { Component } from 'react'; import { Button } from 'antd'; import { withRouter, Prompt } from 'react-router-dom'; // 從react-router-dom中引出Prompt組件class index extends Component {state = {isUserInfoSaved: false,isHoldUpRouter: true, // when的屬性值,初始化必須為true,否則阻塞不了路由跳轉(zhuǎn)。因?yàn)閟etState是異步操作}// 跳轉(zhuǎn)路由handleRouterSwitch = () => {this.props.history.push('/settings/audit_rules')}// 保存用戶信息saveUserInfo = () => {this.setState({isUserInfoSaved: true})}// 處理路由攔截handleRouterHoldUp = (location) => {const { isUserInfoSaved } = this.state;if (!isUserInfoSaved) { // 信息未保存,阻塞路由跳轉(zhuǎn),并彈出提示彈窗return '信息還沒保存,確定離開嗎?'} else if (location.pathname.indexOf('errorUrl') > -1) { // 阻塞跳轉(zhuǎn)到特定的頁面,并彈出提示彈窗return '禁止跳轉(zhuǎn)到指定的errorUrl頁面,確定繼續(xù)跳轉(zhuǎn)嗎'} else {return true; // 符合跳轉(zhuǎn)的條件,釋放路由,路由正常跳轉(zhuǎn)}}render() {const { isHoldUpRouter } = this.state;return (<div><Button onClick={this.handleRouterSwitch}>跳轉(zhuǎn)路由</Button><Button onClick={this.saveUserInfo}>保存信息</Button>{/* 頁面的任何地方加上Prompt組件都生效 */}<Prompt when={isHoldUpRouter} message={this.handleRouterHoldUp} /></div>)} }export default withRouter(index);

    效果:
    當(dāng)用戶點(diǎn)擊“路由跳轉(zhuǎn)”按鈕,阻塞路由跳轉(zhuǎn),彈出提示窗,提示內(nèi)容為message的函數(shù)返回的字符串,當(dāng)用戶點(diǎn)擊“保存信息”按鈕后,再次點(diǎn)擊路由跳轉(zhuǎn)按鈕,路由成功跳轉(zhuǎn),不再彈出提示窗

    自定義Prompt組件的提示彈窗

    從上述示例我們可以看到,Prompt阻塞路由跳轉(zhuǎn)之后彈出的提示彈窗,樣式是系統(tǒng)默認(rèn)的,我們并不可以修改,那么我們能不能自定義提示彈窗呢?接下來我們演示一下如何自定義Prompt的提示彈窗
    需求:

  • 用戶跳轉(zhuǎn)頁面的時候,判斷用戶是否保存了用戶數(shù)據(jù),如果沒有,則阻塞跳轉(zhuǎn),彈出確認(rèn)提示;如果已保存,則正常跳轉(zhuǎn)路由。
  • 確認(rèn)提示框使用自定義提示框
  • 點(diǎn)擊彈窗“取消”按鈕,關(guān)閉彈窗,不跳轉(zhuǎn)頁面;點(diǎn)擊彈窗“確定”按鈕,關(guān)閉彈窗,跳轉(zhuǎn)頁面;
    做法:
    Prompt的when屬性值變量放于state中,message賦值為方法。其中message方法主要用于處理路由攔截后的操作,為了不讓默認(rèn)的系統(tǒng)彈窗彈出,而是彈出我們自己的自定義彈窗,因此這時候message方法只能始終return false。這樣的話,我們主要操作Prompt的when屬性值變化,來攔截或者釋放路由的跳轉(zhuǎn)。
    注意:
    當(dāng)when的屬性值,初始化必須為true,否則阻塞不了路由跳轉(zhuǎn),因?yàn)閟etState是異步操作;同時,當(dāng)setState改變when的屬性值之后,因?yàn)閟etState是異步操作,需要在setState的回調(diào)上手動跳轉(zhuǎn)指定頁面的路由,這樣才能在處理完業(yè)務(wù)邏輯之后,立馬同步跳轉(zhuǎn)路由,否則由于是異步更新state,用戶需要點(diǎn)擊兩次跳轉(zhuǎn)按鈕才能跳轉(zhuǎn)路由。
  • import React, { Component } from 'react'; import { Button, Modal } from 'antd'; import { withRouter, Prompt } from 'react-router-dom'; // 從react-router-dom中引出Prompt組件 import { ExclamationCircleOutlined } from '@ant-design/icons'class index extends Component {state = {isUserInfoSaved: false,isHoldUpRouter: true, // when的屬性值,初始化必須為true,否則阻塞不了路由跳轉(zhuǎn)。因?yàn)閟etState是異步操作whichPathUrlWillTo: '',isShowSavePromptModal: false,}// 跳轉(zhuǎn)路由handleRouterSwitch = () => {this.props.history.push('/settings/audit_rules')}// 保存用戶信息saveUserInfo = () => {this.setState({isUserInfoSaved: true,})}// 處理路由攔截handleRouterHoldUp = (location) => {console.log(location)const { isUserInfoSaved } = this.state;const pathUrl = location.pathname + location.search // // location 攜帶的路徑,即將要跳轉(zhuǎn)的路徑this.setState({whichPathUrlWillTo: pathUrl, // 存儲即將要跳轉(zhuǎn)的pathUrl})if (!isUserInfoSaved) { // 信息未保存,阻塞路由跳轉(zhuǎn),并彈出自定義提示彈窗this.setState({isShowSavePromptModal: true,});} else {this.setState({ // 釋放路由跳轉(zhuǎn)權(quán)限isHoldUpRouter: false}, () => {this.props.history.push(pathUrl) // 手動跳轉(zhuǎn),如果是手動跳轉(zhuǎn),必須放在這里執(zhí)行,因?yàn)閟etState是異步的,如果不放回調(diào)里執(zhí)行手動跳轉(zhuǎn),會陷入Prompt組件的死循環(huán)this.setState({ // 內(nèi)部路由變化,當(dāng)跳轉(zhuǎn)之后,還需要重新關(guān)閉路由跳轉(zhuǎn)權(quán)限,實(shí)現(xiàn)下一次跳轉(zhuǎn)路由的攔截(如果所在頁面的組件已經(jīng)完全銷毀,則不需要重新關(guān)閉路由跳轉(zhuǎn)權(quán)限)isHoldUpRouter: true,})});}return false;}// 處理保存信息提示彈窗的確認(rèn)事件handleSaveModelOK = () => {this.setState({isShowSavePromptModal: false, // 關(guān)閉自定義提示窗isHoldUpRouter: false, // 釋放路由跳轉(zhuǎn)權(quán)限},() => {this.props.history.push(this.state.whichPathUrlWillTo) // 手動跳轉(zhuǎn),如果是手動跳轉(zhuǎn),必須放在這里執(zhí)行,因?yàn)閟etState是異步的,如果不放回調(diào)里執(zhí)行手動跳轉(zhuǎn),會陷入Prompt組件的死循環(huán)this.setState({ // 內(nèi)部路由變化,當(dāng)跳轉(zhuǎn)之后,還需要重新關(guān)閉路由跳轉(zhuǎn)權(quán)限,實(shí)現(xiàn)下一次跳轉(zhuǎn)路由的攔截(如果所在頁面的組件已經(jīng)完全銷毀,則不需要重新關(guān)閉路由跳轉(zhuǎn)權(quán)限)isHoldUpRouter: true,})})}// 處理保存信息提示彈窗的取消事件handleSaveModelCancel = () => {this.setState({isShowSavePromptModal: false, // 關(guān)閉自定義提示窗})}render() {const { isHoldUpRouter, isShowSavePromptModal } = this.state;return (<div><Button onClick={this.handleRouterSwitch}>跳轉(zhuǎn)路由</Button><Button onClick={this.saveUserInfo}>保存信息</Button>{/* 頁面的任何地方加上Prompt組件都生效 */}<Prompt when={isHoldUpRouter} message={this.handleRouterHoldUp} /><Modal title="提示" closable={false} visible={isShowSavePromptModal} onOk={this.handleSaveModelOK} onCancel={this.handleSaveModelCancel}><div style={{fontSize: '14px'}}><ExclamationCircleOutlined /><span style={{marginLeft: '10px'}}>信息還沒保存,確定離開嗎?</span></div></Modal></div>)} }export default withRouter(index);

    方法2:通過history.block實(shí)現(xiàn)react路由跳轉(zhuǎn)攔截功能

    history.block介紹

    我們可用withrouter把histroy注入props,用history.block阻塞路由跳轉(zhuǎn)。

    當(dāng)history.block的回調(diào)函數(shù)返回true,則釋放路由跳轉(zhuǎn);
    當(dāng)history.block的回調(diào)函數(shù)返回false,則阻塞路由跳轉(zhuǎn),不彈出彈窗;
    當(dāng)history.block的回調(diào)函數(shù)返回字符串,則阻塞路由跳轉(zhuǎn),彈出彈窗,彈窗提示信息為回調(diào)函數(shù)的返回字符串

    history.block的回調(diào)函數(shù)接受location參數(shù),location參數(shù)包含即將要跳轉(zhuǎn)到指定路徑的路由信息

    千萬要注意的是:history.block的作用對項(xiàng)目是全局影響的,只要history.block初始化一次,就會對所有的路由跳轉(zhuǎn)做攔截,即使跳出了當(dāng)前路由,在另一個路由做跳轉(zhuǎn)的時候,history.block依舊會生效,并起到路由攔截作用。如果想取消history.block的路由跳轉(zhuǎn)攔截作用,只有對其重新初始化,讓其回調(diào)函數(shù)return true,所以通常做法是,在組件的componentWillUnmount這一生命周期對history.block重新初始化,讓其回調(diào)函數(shù)return true,取消history.block的路由跳轉(zhuǎn)攔截作用

    history.block基本示例

    接下來我們看看在react中如何使用history.block實(shí)現(xiàn)路由攔截:
    在組件的componentDidMount生命周期中初始化history.block,其回調(diào)函數(shù)返回字符串,這會使得在該頁面做路由跳轉(zhuǎn)的時候會被攔截,并彈出提示窗,提示信息為其回調(diào)函數(shù)返回的字符串

    在組件的componentWillUnmount這一生命周期對history.block重新初始化,讓其回調(diào)函數(shù)return true,取消history.block的路由跳轉(zhuǎn)攔截作用,防止其影響其他頁面做路由跳轉(zhuǎn)

    import React, { Component } from 'react'; import { Button } from 'antd'; import { withRouter } from 'react-router-dom';class index extends Component {state = {}componentDidMount() {this.props.history.block(location => { // 當(dāng)history.block的回調(diào)函數(shù)返回true,則釋放路由跳轉(zhuǎn);當(dāng)history.block的回調(diào)函數(shù)返回false,則阻塞路由跳轉(zhuǎn),不彈出彈窗;當(dāng)history.block的回調(diào)函數(shù)返回字符串,則阻塞路由跳轉(zhuǎn),彈出彈窗,彈窗提示信息為回調(diào)函數(shù)的返回字符串(點(diǎn)擊確定,釋放路由,繼續(xù)跳轉(zhuǎn)到指定頁面,點(diǎn)擊取消,關(guān)閉彈窗,繼續(xù)阻塞路由跳轉(zhuǎn))console.log(location) // history.block的回調(diào)函數(shù)接手location參數(shù),location參數(shù)包含即將要跳轉(zhuǎn)到指定路徑的路由信息// return true;// return false;return '信息還沒保存,確定離開嗎?'});}componentWillUnmount() { // history.block的作用對項(xiàng)目是全局影響的,組件的componentWillUnmount一定要記得重新初始化history.block,讓其回調(diào)函數(shù)返回true,取消history.block的路由跳轉(zhuǎn)攔截作用,防止其影響其他頁面做路由跳轉(zhuǎn)this.props.history.block(location => { // 當(dāng)history.block的回調(diào)函數(shù)返回true,則釋放路由跳轉(zhuǎn);當(dāng)history.block的回調(diào)函數(shù)返回false,則阻塞路由跳轉(zhuǎn),不彈出彈窗;當(dāng)history.block的回調(diào)函數(shù)返回字符串,則阻塞路由跳轉(zhuǎn),彈出彈窗,彈窗提示信息為回調(diào)函數(shù)的返回字符串(點(diǎn)擊確定,釋放路由,繼續(xù)跳轉(zhuǎn)到指定頁面,點(diǎn)擊取消,關(guān)閉彈窗,繼續(xù)阻塞路由跳轉(zhuǎn))console.log(location) // history.block的回調(diào)函數(shù)接手location參數(shù),location參數(shù)包含即將要跳轉(zhuǎn)到指定路徑的路由信息return true;// return false;// return '信息還沒保存,確定離開嗎?'});}// 跳轉(zhuǎn)路由handleRouterSwitch = () => {this.props.history.push('/outside')}render() {return (<div><Button onClick={this.handleRouterSwitch}>跳轉(zhuǎn)路由</Button></div>)} }export default withRouter(index);

    點(diǎn)擊“路由跳轉(zhuǎn)”按鈕,觸發(fā)路由跳轉(zhuǎn)事件,history.block阻塞路由跳轉(zhuǎn),并彈出提示窗,提示信息為history.block回調(diào)函數(shù)return的字符串

    點(diǎn)擊彈窗“確定”按鈕,釋放路由,繼續(xù)跳轉(zhuǎn)到目標(biāo)url
    點(diǎn)擊彈窗“取消”按鈕,關(guān)閉彈窗,路由不做跳轉(zhuǎn)

    history.block使用示例(自定義彈窗)

    從上述示例我們可以看到,history.block阻塞路由跳轉(zhuǎn)之后彈出的提示彈窗,樣式是系統(tǒng)默認(rèn)的,我們并不可以修改,那么我們能不能自定義提示彈窗呢?接下來我們演示一下如何自定義history.block的提示彈窗
    需求:

  • 用戶跳轉(zhuǎn)頁面的時候,判斷用戶是否保存了用戶數(shù)據(jù),如果沒有,則阻塞跳轉(zhuǎn),彈出確認(rèn)提示;如果已保存,則正常跳轉(zhuǎn)路由。
  • 確認(rèn)提示框使用自定義提示框
  • 點(diǎn)擊彈窗“取消”按鈕,關(guān)閉彈窗,不跳轉(zhuǎn)頁面;點(diǎn)擊彈窗“確定”按鈕,關(guān)閉彈窗,跳轉(zhuǎn)頁面;
  • 做法:
    history.block只有在其回調(diào)函數(shù)返回值為字符串的時候,才會彈出系統(tǒng)彈窗,而返回布爾值的時候,不會彈出彈窗,我們僅僅需要history.block的路由攔截功能,不讓其彈出系統(tǒng)彈窗,而是彈出自定義彈窗,那么我們讓history.block的回調(diào)函數(shù)返回true就可以釋放路由,返回false就可以攔截路由,在返回false的同時,展示自定義的彈窗。通過重新初始化history.block,操作history.block的回調(diào)函數(shù)返回值,來攔截或者釋放路由的跳轉(zhuǎn)。

    import React, { Component } from 'react'; import { Button, Modal } from 'antd'; import { withRouter } from 'react-router-dom'; import { ExclamationCircleOutlined } from '@ant-design/icons'class index extends Component {state = {isUserInfoSaved: false,whichPathUrlWillTo: '',isShowSavePromptModal: false,}componentDidMount() {this.props.history.block(this.handleRouterHoldUp);}componentWillUnmount() { // history.block的作用對項(xiàng)目是全局影響的,組件的componentWillUnmount一定要記得重新初始化history.block,讓其回調(diào)函數(shù)返回true,取消history.block的路由跳轉(zhuǎn)攔截作用,防止其影響其他頁面做路由跳轉(zhuǎn)this.props.history.block(location => { // 當(dāng)history.block的回調(diào)函數(shù)返回true,則釋放路由跳轉(zhuǎn);當(dāng)history.block的回調(diào)函數(shù)返回false,則阻塞路由跳轉(zhuǎn),不彈出彈窗;當(dāng)history.block的回調(diào)函數(shù)返回字符串,則阻塞路由跳轉(zhuǎn),彈出彈窗,彈窗提示信息為回調(diào)函數(shù)的返回字符串(點(diǎn)擊確定,釋放路由,繼續(xù)跳轉(zhuǎn)到指定頁面,點(diǎn)擊取消,關(guān)閉彈窗,繼續(xù)阻塞路由跳轉(zhuǎn))console.log(location) // history.block的回調(diào)函數(shù)接手location參數(shù),location參數(shù)包含即將要跳轉(zhuǎn)到指定路徑的路由信息return true;// return false;// return '信息還沒保存,確定離開嗎?'});}// 跳轉(zhuǎn)路由handleRouterSwitch = () => {this.props.history.push('/machine_learning/permission_settings')}// 保存用戶信息saveUserInfo = () => {this.setState({isUserInfoSaved: true,})}// 處理路由攔截handleRouterHoldUp = (location) => {console.log(location)const { isUserInfoSaved } = this.state;const pathUrl = location.pathname + location.search // // location 攜帶的路徑,即將要跳轉(zhuǎn)的路徑this.setState({whichPathUrlWillTo: pathUrl, // 存儲即將要跳轉(zhuǎn)的pathUrl})if (!isUserInfoSaved) { // 信息未保存,阻塞路由跳轉(zhuǎn),并彈出自定義提示彈窗this.setState({isShowSavePromptModal: true,});} else {this.props.history.block(location => { // 重新初始化history.block,釋放路由跳轉(zhuǎn)權(quán)限return true;});this.props.history.push(pathUrl) // 手動跳轉(zhuǎn)}return false;}// 處理保存信息提示彈窗的確認(rèn)事件handleSaveModelOK = () => {this.setState({isShowSavePromptModal: false, // 關(guān)閉自定義提示窗})this.props.history.block(location => { // 重新初始化history.block,釋放路由跳轉(zhuǎn)權(quán)限return true;});this.props.history.push(this.state.whichPathUrlWillTo) // 手動跳轉(zhuǎn)}// 處理保存信息提示彈窗的取消事件handleSaveModelCancel = () => {this.setState({isShowSavePromptModal: false, // 關(guān)閉自定義提示窗})}render() {const { isShowSavePromptModal } = this.state;return (<div><Button onClick={this.handleRouterSwitch}>跳轉(zhuǎn)路由</Button><Button onClick={this.saveUserInfo}>保存信息</Button><Modal title="提示" closable={false} visible={isShowSavePromptModal} onOk={this.handleSaveModelOK} onCancel={this.handleSaveModelCancel}><div style={{fontSize: '14px'}}><ExclamationCircleOutlined /><span style={{marginLeft: '10px'}}>信息還沒保存,確定離開嗎?</span></div></Modal></div>)} }export default withRouter(index);

    文章參考

    https://www.cnblogs.com/tirybk/p/14688240.html
    https://www.cnblogs.com/amiezhang/p/13207409.html
    https://github.com/mirrorjs/mirror/issues/78
    https://segmentfault.com/a/1190000019105896
    https://segmentfault.com/a/1190000020241389?utm_source=tag-newest
    https://segmentfault.com/a/1190000039190541

    總結(jié)

    以上是生活随笔為你收集整理的react实现路由跳转拦截功能(导航守卫)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。