vue路由-3-監(jiān)聽(tīng)-守衛(wèi)-解決created只走一次的問(wèn)題

1. 前言

1.路由確實(shí)在vue大型項(xiàng)目中聽(tīng)常用的,挺重要的,但是一般的小項(xiàng)目其實(shí)不用也沒(méi)事
2.大家覺(jué)得難的 可能重點(diǎn)是路由守衛(wèi)
3.那就試試自己能不能講明白吧
4.當(dāng)然還是建議大家看看 官網(wǎng)的路由守衛(wèi)


2. 先從路由監(jiān)聽(tīng)說(shuō)起吧

2.1 首先路由系列的文章vue路由-2編程式導(dǎo)航存在通過(guò)路由切換的時(shí)候,created直走一次的問(wèn)題,

2.2 解決方案 監(jiān)聽(tīng) -1

參數(shù)的名字 一般都叫to from或者 newV, oldV
to: Route: 即將要進(jìn)入的目標(biāo) 路由對(duì)象
from: Route: 當(dāng)前導(dǎo)航正要離開(kāi)的路由

            watch:{
                   $route(to,from){
                    console.log(from.path);//從哪來(lái)
                    console.log(to.path);//到哪去
            //界面變化了就發(fā)請(qǐng)求
               }
            },

這種寫法也有個(gè)問(wèn)題,第一次的時(shí)候不走


2.3 解決方案 監(jiān)聽(tīng)-2

immediate:true 設(shè)置 立刻監(jiān)聽(tīng),第一次切換也會(huì)走的

    watch:{
            $route:{
                immediate:true,
                 handler(newValue,oldValue){
                        console.log("詳情頁(yè)---newV:",newValue);
                         console.log("詳情頁(yè)---oldV:",oldValue);
                      }
               },
        },

3.導(dǎo)航守衛(wèi)

3.1 官方定義

正如其名,vue-router 提供的導(dǎo)航守衛(wèi)主要用來(lái)通過(guò)跳轉(zhuǎn)或取消的方式守衛(wèi)導(dǎo)航。有多種機(jī)會(huì)植入路由導(dǎo)航過(guò)程中:全局的, 單個(gè)路由獨(dú)享的, 或者組件級(jí)的。


3.2 場(chǎng)景

路由守衛(wèi)嘛 就是保護(hù)路由的 ,怎么保護(hù)呢
主要就是在進(jìn)入路由之前進(jìn)行攔截

一般都是 某些界面必須登錄才能訪問(wèn)的時(shí)候做個(gè)守衛(wèi),比如
最近某些購(gòu)物類網(wǎng)站,點(diǎn)擊購(gòu)物車相關(guān)操作話,如果你沒(méi)有登錄的話,會(huì)直接跳轉(zhuǎn)到登錄界面;
在以前是會(huì)正常跳到購(gòu)物車界面,付賬的時(shí)候在登錄,登錄后購(gòu)物車信息是都在的


5. 全局守衛(wèi)配置

5.1 標(biāo)記需要進(jìn)行守衛(wèi)的路由

一般通過(guò)路由配置meta屬性
路由文件

   {
    path: '/address',
    name: 'Address',
    component: () => import('../views/address.vue'),
    meta:{
       title: "標(biāo)題",
       icon: "圖標(biāo)",
       needLogin:true
    }
  },

1.meta哈哈沒(méi)想到這個(gè)時(shí)候正式元宇宙大火的概念
2.扯回整體, 這里的meta是一些原配置信息
3.needLogin 用來(lái)標(biāo)記某個(gè)頁(yè)面路由是否需要登錄才能訪問(wèn)
4.title實(shí)際開(kāi)發(fā)中,如果配置菜單 也可以配置標(biāo)題
5.icon實(shí)際開(kāi)發(fā)中,如果配置菜單 也可以配置菜單圖標(biāo)


5.2守衛(wèi)邏輯

  1. 判斷哪個(gè)路由需要守衛(wèi)if(to.meta.needLogin)
  2. 不需要守衛(wèi)的 直接 走else next()
  3. 需要守衛(wèi)的進(jìn)行第二步判斷, 當(dāng)前是否登錄
    登錄的時(shí)候發(fā)請(qǐng)求 請(qǐng)求成功 存放 一個(gè)auth或者token到本地localStorage
  4. 如果現(xiàn)在已經(jīng)登錄 直接 next()放行
    5.如果沒(méi)登錄 嘿嘿 此路是我開(kāi),此樹(shù)是我栽,要想過(guò),得聽(tīng)話,
    回去登錄去

注意的是 這里跳轉(zhuǎn)到登錄界面,需要把攔截路由的地址傳過(guò)去,
為啥傳???
那還不是為了用戶體驗(yàn),為了顧客,為了邏輯閉環(huán)

比如用戶從點(diǎn)擊購(gòu)物車界面 跳轉(zhuǎn)到了登錄界面,用戶登錄后,肯定要給界面重置到 購(gòu)物車界面嘛,


5.3 具體守衛(wèi)代碼 方式-1

// 全局守衛(wèi)
router.beforeEach((to,from,next)=>{
  // 判斷路由是否需要守衛(wèi)
  //meta數(shù)據(jù)的方式
  if(to.meta.needLogin){
    // 是否登錄
    if(localStorage.token){
      next()
    }else{
      next("/login?redirect="+to.fullPath)
    }
  }else{
    //不需要守衛(wèi),直接放行
    next()
  }
})
export default router

5.4具體守衛(wèi)代碼 方式-2

router.beforeEach((to, from) => {
  if (to.meta.needLogin) {//說(shuō)明當(dāng)前路由需要登錄之后才可進(jìn)入
    if (!localStorage.token) {//還沒(méi)登錄 不為空 就行 簡(jiǎn)單的判斷
      // return "/login?redirect=" + to.name; 
      return "/login?redirect=" + to.fullPath;
    }
  }
})

這個(gè)不用 next,但如果參數(shù)寫了next 就必須用,不然不放行嘛,界面就一個(gè)也出不來(lái)
to.name 的方式 傳的是 命名路由 跳轉(zhuǎn)的時(shí)候也需要使用命名路由跳轉(zhuǎn)

    this.$router.push({ name: this.$route.query.redirect});

to.fullPath 的方式 傳的是 path路徑
push也行,但是也可用 replace

    this.$router.replace(this.$route.query.to);

6. 登錄后跳回去的配置

loginBtn() {
      this.isdisabled = true;
      setTimeout(() => {
        alert("登錄成功");
        this.isdisabled = false;
        localStorage.token = "yzs假冒token";
        // 登錄成功之后 回到被攔截的頁(yè)面
       this.$router.replace(this.$route.query.redirect);
        }
      }, 3000);
    },
1.png
守衛(wèi)的時(shí)候傳參方式

1.可以傳 通過(guò)query傳遞 path路徑
2.也可以通過(guò) params 傳參
3.注意登錄成功后 獲取值的方式就行

        query:{redirect:"/two"} ,
        params: { toRouterName: to.name }})

命名路由的寫法

      this.$router.push({ name: this.$route.params.toRouterName });

這樣就形成了邏輯閉環(huán) ,當(dāng)然你還需退出或者注銷的時(shí)候修改狀態(tài)


7.單個(gè)路由守衛(wèi)

全局守衛(wèi),肯定是每個(gè)路由跳轉(zhuǎn)都要進(jìn)行判斷的,也就是each遍歷,這里面的效率問(wèn)題就需要考慮
所以,如果只是極個(gè)別的路由需要判斷,那就單獨(dú)守衛(wèi)
比如保護(hù)整村的人,和保護(hù)一個(gè)人那是完全不一樣的

注意和全局的不同

  1. 鉤子不一樣了,這個(gè)是Enter進(jìn)到這個(gè)路由了,判斷
    2.因?yàn)橐呀?jīng)進(jìn)到這個(gè)路由了,自然也不需要在判斷哪個(gè)路由需要守衛(wèi)了
  2. 直接判斷登錄狀態(tài)就行
  {
    path: '/cart',
    name: 'Cart',
    component: () => import("@/views/cart.vue"),
    meta: {
      title: "標(biāo)題",
      icon: "圖標(biāo)",
      needLogin: true
    },
    //************* */ 單個(gè)的路由守衛(wèi)
    beforeEnter(to, from, next) {
      //  判斷當(dāng)前是否登錄
      if (localStorage.token) {
        next()
      } else {
        next({ name: "Three",
        query:{to:"/cart"} ,
        params: { toRouterName: to.name },})
      }
    }
  },

8. 組件級(jí)守衛(wèi)

1.和 methds 是同級(jí)的
2.beforeRouteEnter 和 單獨(dú)的守衛(wèi)beforeEnter寫法是不一樣的
3.這個(gè)是存儲(chǔ) localStorage的邏輯
4.login頁(yè)和單個(gè)守衛(wèi)用的是一樣的

 beforeRouteEnter(to, from, next) {
    // 當(dāng)前是否登錄
    if (localStorage.token) {
      next();
    } else {
      next({ name: "Login", params: { toRouterName: to.name } });
    }
  },

9. 組件級(jí)守衛(wèi) 鉤子詳解

const Foo = {
  template: `...`,
  beforeRouteEnter(to, from, next) {
    // 在渲染該組件的對(duì)應(yīng)路由被 confirm 前調(diào)用
    // 不!能妻献!獲取組件實(shí)例 `this`
    // 因?yàn)楫?dāng)守衛(wèi)執(zhí)行前,組件實(shí)例還沒(méi)被創(chuàng)建
  },
  beforeRouteUpdate(to, from, next) {
    // 在當(dāng)前路由改變,但是該組件被復(fù)用時(shí)調(diào)用
    // 舉例來(lái)說(shuō),對(duì)于一個(gè)帶有動(dòng)態(tài)參數(shù)的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉(zhuǎn)的時(shí)候礁扮,
    // 由于會(huì)渲染同樣的 Foo 組件知举,因此組件實(shí)例會(huì)被復(fù)用。而這個(gè)鉤子就會(huì)在這個(gè)情況下被調(diào)用太伊。
    // 可以訪問(wèn)組件實(shí)例 `this`
  },
  beforeRouteLeave(to, from, next) {
    // 導(dǎo)航離開(kāi)該組件的對(duì)應(yīng)路由時(shí)調(diào)用
    // 可以訪問(wèn)組件實(shí)例 `this`
  }
}

1. 注意 Enter鉤子不能訪問(wèn) this

因?yàn)槭匦l(wèi)在導(dǎo)航確認(rèn)前被調(diào)用雇锡,因此即將登場(chǎng)的新組件還沒(méi)被創(chuàng)建。

不過(guò)僚焦,你可以通過(guò)傳一個(gè)回調(diào)給 next來(lái)訪問(wèn)組件實(shí)例锰提。在導(dǎo)航被確認(rèn)的時(shí)候執(zhí)行回調(diào),并且把組件實(shí)例作為回調(diào)方法的參數(shù)。

beforeRouteEnter (to, from, next) {
  next(vm => {
    // 通過(guò) `vm` 訪問(wèn)組件實(shí)例
  })
}

注意

beforeRouteEnter 是支持給next傳遞回調(diào)的唯一守衛(wèi)立肘。對(duì)于 beforeRouteUpdatebeforeRouteLeave來(lái)說(shuō)边坤,this已經(jīng)可用了,所以不支持傳遞回調(diào)谅年,因?yàn)闆](méi)有必要了茧痒。


10.完整的導(dǎo)航解析流程

1.導(dǎo)航被觸發(fā)。
2.在失活的組件里調(diào)用 beforeRouteLeave守衛(wèi)融蹂。
3.調(diào)用全局的beforeEach守衛(wèi)旺订。
4.在重用的組件里調(diào)用 beforeRouteUpdate 守衛(wèi) (2.2+)。
5.在路由配置里調(diào)用 beforeEnter超燃。
6.解析異步路由組件区拳。
7.在被激活的組件里調(diào)用beforeRouteEnter
8.調(diào)用全局的 beforeResolve守衛(wèi) (2.5+)意乓。
9.導(dǎo)航被確認(rèn)樱调。
10.調(diào)用全局的afterEach 鉤子。
11.觸發(fā) DOM 更新洽瞬。
12.調(diào)用beforeRouteEnter 守衛(wèi)中傳給next的回調(diào)函數(shù)本涕,創(chuàng)建好的組件實(shí)例會(huì)作為回調(diào)函數(shù)的參數(shù)傳入。


11. 想學(xué)習(xí)更多的實(shí)戰(zhàn)配置 可以去看下各大開(kāi)源的項(xiàng)目源碼

比如各大框架的admin模板


參考資料

路由守衛(wèi)


初心

我所有的文章都只是基于入門伙窃,初步的了解菩颖;是自己的知識(shí)體系梳理;
如果能幫助到有緣人,非常的榮幸,一切為了部落的崛起;
共勉
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市为障,隨后出現(xiàn)的幾起案子晦闰,更是在濱河造成了極大的恐慌,老刑警劉巖鳍怨,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呻右,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡鞋喇,警方通過(guò)查閱死者的電腦和手機(jī)声滥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)侦香,“玉大人落塑,你說(shuō)我怎么就攤上這事」藓” “怎么了憾赁?”我有些...
    開(kāi)封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)散吵。 經(jīng)常有香客問(wèn)我龙考,道長(zhǎng)蟆肆,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任晦款,我火速辦了婚禮炎功,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘柬赐。我一直安慰自己亡问,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布肛宋。 她就那樣靜靜地躺著州藕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪酝陈。 梳的紋絲不亂的頭發(fā)上床玻,一...
    開(kāi)封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音沉帮,去河邊找鬼锈死。 笑死,一個(gè)胖子當(dāng)著我的面吹牛穆壕,可吹牛的內(nèi)容都是我干的待牵。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼喇勋,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼缨该!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起川背,我...
    開(kāi)封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤贰拿,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后熄云,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體膨更,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年缴允,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了荚守。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡练般,死狀恐怖矗漾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情踢俄,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布晴及,位于F島的核電站都办,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜琳钉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一势木、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧歌懒,春花似錦啦桌、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至验烧,卻和暖如春板驳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背碍拆。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工若治, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人感混。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓端幼,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親弧满。 傳聞我的和親對(duì)象是個(gè)殘疾皇子婆跑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容