国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

react17+antd4 Menu 點(diǎn)擊菜單收起其他展開的所有菜單、頁(yè)面刷新時(shí)設(shè)置菜單的選中狀態(tài)和展開狀態(tài)

這篇具有很好參考價(jià)值的文章主要介紹了react17+antd4 Menu 點(diǎn)擊菜單收起其他展開的所有菜單、頁(yè)面刷新時(shí)設(shè)置菜單的選中狀態(tài)和展開狀態(tài)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

export const asyncRouterMap = [
    {
        path: '/page1',
        title: 'page1',
        icon: 'HomeOutlined',
    }, {
        path: '/page2',
        title: 'page2',
        icon: 'HomeOutlined',
    }, {
        path: '/page3',
        title: 'page3',
        icon: 'HomeOutlined',
        children: [
            {
                path: '/page301',
                title: 'page301',
                icon: 'HomeOutlined',
            }, {
                path: '/page302',
                title: 'page302',
                icon: 'HomeOutlined',
            }, {
                path: '/page303',
                title: 'page303',
                icon: 'HomeOutlined',
            }
        ]
    },{
        path: '/page4',
        title: 'page4',
        icon: 'HomeOutlined',
        children: [
            {
                path: '/page401',
                title: 'page401',
                icon: 'HomeOutlined',
            }, {
                path: '/page402',
                title: 'page402',
                icon: 'HomeOutlined',
            }
        ]
    }
]

使用path當(dāng)作Menu的key.

1.菜單欄展開和回收事件

點(diǎn)擊菜單,收起其他展開的所有菜單,只留下一個(gè)。

Menu的onOpenChange方法:SubMenu 展開/ 關(guān)閉的回調(diào)函數(shù),展開和回收某項(xiàng)菜單時(shí)的事件。
Menu的openKeys屬性:當(dāng)前展開的SubMenu菜單項(xiàng)的key數(shù)組,當(dāng)前菜單展開項(xiàng)的key數(shù)組。

當(dāng)前要展開哪一項(xiàng)的openKeys將來(lái)是要變化的,需要存到state中。

state={
	openKey:['']
}

//展開和回收某項(xiàng)菜單,把openKeys的數(shù)組值變?yōu)閗eys數(shù)組的最后一項(xiàng),只要一項(xiàng)是展開的,就是我剛點(diǎn)擊的這一項(xiàng)
handleOpenChange=(keys)=>{
	//keys是一個(gè)字符串?dāng)?shù)組,記錄了當(dāng)前哪一項(xiàng)是展開的(用key來(lái)記錄)
	
   	//console.log(keys) 
  	/* 點(diǎn)擊page3 keys輸出["",'/page3'],再點(diǎn)擊page4 keys輸出["",'/page4'],點(diǎn)擊誰(shuí)keys數(shù)組的最后一項(xiàng)就是誰(shuí)*/
	this.setState({
      	 openKeys:[keys[keys.length-1]]
    })
}

<Menu
	defaultSelectedKeys={['/home']}
	mode="inline"
	theme="dark"
	style={{ height: "100vh" }}
	openKeys={openKeys}
	onOpenChange={this.handleOpenChange}
>

2. 刷新時(shí)默認(rèn)當(dāng)前選中項(xiàng)樣式的處理

根據(jù)用戶的操作習(xí)慣,選中一個(gè)二級(jí)菜單節(jié)點(diǎn)的時(shí)候,刷新頁(yè)面的時(shí)候應(yīng)該保持用戶之前的選中狀態(tài),并且二級(jí)菜單展開項(xiàng)應(yīng)該默認(rèn)展開。

2.1 刷新頁(yè)面菜單保持用戶之前的選中狀態(tài)

現(xiàn)在的情況是點(diǎn)擊page2頁(yè)面,組件在page2頁(yè)面,在這時(shí)刷新頁(yè)面,導(dǎo)航欄的高亮選中變成了第一項(xiàng),但是組件還是page2頁(yè)面,出現(xiàn)了選中菜單與頁(yè)面不符合的情況,我們希望的是點(diǎn)擊了刷新頁(yè)面之后組件在page2頁(yè)面并且導(dǎo)航欄選中項(xiàng)也是這個(gè)。

Menu的selectedKeys屬性:表示當(dāng)前樣式所在的選中項(xiàng)key,不能直接寫死,通過(guò)獲取當(dāng)前的路徑拿到key。

怎么獲取當(dāng)前路徑呢?對(duì)于類組件,使用this.props.location.pathname拿到的就是當(dāng)前頁(yè)面的路徑;對(duì)于函數(shù)式組件,使用hooks的useLocation().pathname拿到當(dāng)前頁(yè)面的路徑。

獲取到當(dāng)前頁(yè)面的路徑后作為值修改selectedKeys的值。

state={
	openKey:[''],
	selectedKey:['']
}


 /* this.changeSelectKeys()這個(gè)函數(shù)要在要在componentDidMount中調(diào)用一次,
 再在componentUpdate中再調(diào)用。
 這是因?yàn)閏omponentDidMount只在第一次render之后執(zhí)行一次,
 后續(xù)的rendr執(zhí)行后會(huì)執(zhí)行componentDidUpdate;
 從登錄頁(yè)進(jìn)入到首頁(yè)后會(huì)先mount,然后有setState,會(huì)發(fā)生update,
 點(diǎn)擊切換菜單欄只會(huì)再執(zhí)行componentUpdate,
 不會(huì)再執(zhí)行componentDidMount了。*/
/*在componentDidUpdate生命周期方法中加入
判斷當(dāng)前頁(yè)面路徑是否與上一個(gè)頁(yè)面路徑相同
是為了避免不必要的狀態(tài)更新和重新渲染,從而防止死循環(huán)的發(fā)生。
如果沒(méi)有這個(gè)判斷,每次組件更新時(shí)都會(huì)執(zhí)行changeSelectedKey方法,
該方法會(huì)根據(jù)當(dāng)前路徑更新菜單狀態(tài)。
然而,更新狀態(tài)又會(huì)導(dǎo)致組件重新渲染,這將再次觸發(fā)componentDidUpdate方法,形成一個(gè)無(wú)限循環(huán)。
通過(guò)添加判斷,我們可以確保只有在當(dāng)前頁(yè)面路徑與上一個(gè)頁(yè)面路徑不同時(shí)才會(huì)更新菜單狀態(tài),
從而避免了不必要的循環(huán)更新。*/
componentDidUpdate(prevProps) {
	// 這里必須要有這個(gè)前后路徑是否一致的判斷,否則會(huì)出現(xiàn)死循環(huán)
    if (prevProps.location.pathname !== this.props.location.pathname) {
      this.changeSelected();
    }
}
componentDidMount() {
     this.changeSelected();
}
changeSelected = () => {
    //根據(jù)當(dāng)前頁(yè)面路由修改當(dāng)前選中的菜單項(xiàng)key數(shù)組
    //獲取當(dāng)前頁(yè)面路徑(切割后的key)  由于我們?cè)O(shè)計(jì)的當(dāng)前頁(yè)面路徑與key不完全一致需要做切割
    const currentRoute = this.props.location.pathname.split('/index')[1]
    this.setState({
        selectedKey: [currentRoute]
    })
}


<Menu
	defaultSelectedKeys={['/home']}
	selectedKeys={selectedKey}
	mode="inline"
	theme="dark"
	style={{ height: "100vh" }}
	openKeys={openKeys}
	onOpenChange={this.handleOpenChange}
>

現(xiàn)在能夠?qū)崿F(xiàn)的是頁(yè)面刷新保持用戶的選中狀態(tài),但是當(dāng)我們點(diǎn)擊的是page301再刷新頁(yè)面時(shí),雖然該菜單項(xiàng)會(huì)被選中,但是菜單欄中page301沒(méi)有被展開,需要再進(jìn)行下面的配置。

2.2 配置展開項(xiàng)openKeys的初始值

需要修改openKeys數(shù)組,openKeys的展開項(xiàng)是不能寫死的,刷新頁(yè)面后誰(shuí)展開是跟路徑有關(guān)的。

整體思路是:拿著this.props.location.pathname與items數(shù)組的每一項(xiàng)的children的key值進(jìn)行對(duì)比,如果找到了相等了,就要他上一級(jí)的key給到openKeys數(shù)組的元素,作為初始值。
(這個(gè)思路更加通用一些)

整體思路:根據(jù)this.props.location.pathname拿到它上一級(jí)的key,比如’/page3/page301’要想辦法拿到‘/page3’,’/page3/page301/page30101’要想辦法拿到’/page3/page301’,把openKeys的值改為拿到的它上一級(jí)的key,這個(gè)操作可以跟隨changeSelectedKey操作放在一個(gè)函數(shù)中。(這種方法比較簡(jiǎn)單,但是要求key的格式必須是 /page3/page301 這樣的)

    changeSelected = () => {
        //根據(jù)當(dāng)前頁(yè)面路由修改當(dāng)前選中的菜單項(xiàng)key數(shù)組
        //獲取當(dāng)前頁(yè)面路徑(切割后的key)  由于我們?cè)O(shè)計(jì)的當(dāng)前頁(yè)面路徑與key不完全一致需要做切割
        const currentRoute = this.getCurrentRoute()

        // pathname:  /home   /student/exam    /student/exam/a
        // 想要的結(jié)果  /home   /student          /student/exam
        //先拆開在拼起來(lái)
        //拆開    ['',home] ['','student','exam']    ['','student','exam','a']
        //取1~倒數(shù)第二項(xiàng)    ['student']   ['student','exam']
        //拼接起來(lái)
        let openKeys=[]
        if(currentRoute.split('/').length>2){
            openKeys=[`/${currentRoute.split('/').slice(1, -1).join('/')}`]
        }
        // console.log(openKeys)
        this.setState({
            selectedKey: [currentRoute],
            openKeys
        })        
    }

componentDidMount用于刷新頁(yè)面時(shí)頁(yè)面卸載又重新掛載,componentDidUpdate用于不刷新頁(yè)面只點(diǎn)擊菜單欄。

在使用React類組件時(shí),調(diào)用updateMenuState方法既在componentDidMount中也在componentDidUpdate中是為了確保無(wú)論組件是在初次掛載還是在更新后,都能根據(jù)當(dāng)前的路由路徑正確設(shè)置菜單的選中狀態(tài)和展開狀態(tài)。

這兩個(gè)生命周期方法各自承擔(dān)著不同的職責(zé):

  • componentDidMount:這個(gè)方法在組件首次渲染到DOM中后被調(diào)用。此時(shí),你可以進(jìn)行API調(diào)用、設(shè)置狀態(tài)等操作。對(duì)于導(dǎo)航菜單來(lái)說(shuō),當(dāng)組件首次加載時(shí),你需要根據(jù)當(dāng)前的路由路徑初始化菜單的狀態(tài),包括哪個(gè)菜單項(xiàng)被選中以及哪些子菜單應(yīng)該展開。因?yàn)樵趹?yīng)用首次加載時(shí),用戶可能直接通過(guò)URL訪問(wèn)特定頁(yè)面,所以需要在這個(gè)時(shí)刻根據(jù)URL設(shè)置正確的菜單狀態(tài)。

  • componentDidUpdate:這個(gè)方法在組件更新后被調(diào)用。在React中,組件的更新可能由props或state的改變引起,也可能是由于父組件的重新渲染觸發(fā)。在導(dǎo)航菜單的情況下,用戶可能通過(guò)點(diǎn)擊鏈接或其他方式導(dǎo)致路由的變化,因此需要在組件更新后再次檢查當(dāng)前的路由路徑,以確保菜單狀態(tài)與當(dāng)前頁(yè)面匹配。因此,在componentDidUpdate中調(diào)用updateMenuState方法,可以在組件更新后根據(jù)新的路由路徑更新菜單狀態(tài),保持菜單的正確顯示。

參考內(nèi)容:React 中使用antd,刷新時(shí)被選中的menu二級(jí)菜單初始化的展開問(wèn)題
??????????????????React+Ant Design 4.4.1實(shí)現(xiàn)左側(cè)二級(jí)導(dǎo)航(可配置路由、所有路由層級(jí)可統(tǒng)一、可根據(jù)路由高亮菜單項(xiàng)、刷新時(shí)可自動(dòng)展開定位到當(dāng)前路由)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-850316.html

到了這里,關(guān)于react17+antd4 Menu 點(diǎn)擊菜單收起其他展開的所有菜單、頁(yè)面刷新時(shí)設(shè)置菜單的選中狀態(tài)和展開狀態(tài)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包