vue-router深度解析情臭,全方位搞定路由!

SPA單頁(yè)應(yīng)用

傳統(tǒng)的項(xiàng)目大多使用多頁(yè)面結(jié)構(gòu)赌蔑,需要切換內(nèi)容的時(shí)候我們往往會(huì)進(jìn)行單個(gè)html文件的跳轉(zhuǎn)俯在,這個(gè)時(shí)候受網(wǎng)絡(luò)、性能影響娃惯,瀏覽器會(huì)出現(xiàn)不定時(shí)間的空白界面跷乐,用戶體驗(yàn)不好。現(xiàn)在的應(yīng)用都流行SPA應(yīng)用(single page application)趾浅,單頁(yè)面應(yīng)用就是用戶通過(guò)某些操作更改地址欄url之后愕提,動(dòng)態(tài)的進(jìn)行不同模板內(nèi)容的無(wú)刷新切換,用戶體驗(yàn)好皿哨。

Vue中會(huì)使用官方提供的vue-router插件來(lái)使用單頁(yè)面浅侨,原理就是通過(guò)檢測(cè)地址欄變化后將對(duì)應(yīng)的路由組件進(jìn)行切換(卸載和安裝)。

簡(jiǎn)單路由的實(shí)現(xiàn)

  1. 如果不是使用腳手架創(chuàng)建的項(xiàng)目证膨,需要手動(dòng)安裝vue-router路由模塊如输。

     cnpm install vue-router -S
    
  2. 引入vue-router,如果是在腳手架中,引入VueRouter之后挨决,需要通過(guò)Vue.use來(lái)注冊(cè)插件请祖。

    import Vue from 'vue'
    import Router from 'vue-router'
    Vue.use(Router)//讓vue可以使用vue-router插件
    

    注冊(cè)vue-router插件之后,this上就有了$route/router屬性脖祈。

image
  1. 創(chuàng)建router路由器肆捕,并導(dǎo)出。

    let router = new Router({
      routes:[
    
      ]
    })
    
    export default router;
    
  2. 在根實(shí)例里注入router

    new Vue({
      //掛載router
      router,//為了可以讓組件使用this.$route,this.$router的一些api屬性或者方法
      store,
      render: h => h(App)
    }).$mount('#app')
    
    

    此時(shí)組件可以通過(guò)this.$router/router來(lái)使用路由相關(guān)功能的api盖高。

    image
  3. 創(chuàng)建router路由表

    let router = new Router({
      routes:[
        {
          path:"/home",component:Home
        },
        {
          path: "/list", component: List
        },
        {
          path: "/mine", component: Mine
        }
      ]
    })
    
  4. 在App.vue中利用router-view來(lái)指定路由切換的位置

    <template>
      <div id="app">
        Hello app.vue!
        <!-- 顯示路由組件的位置 -->
        <router-view></router-view>
      </div>
    </template>
    

    路由切換效果:

    image
  5. 使用router-link來(lái)創(chuàng)建切換路由的工具

    <div>
          <router-link to = "/home">首頁(yè)</router-link>
          <router-link to = "/list">列表</router-link>
          <router-link to = "/mine">我的</router-link>
        </div>
    
    image

    <router-link>會(huì)渲染成a標(biāo)簽慎陵,添加to屬性來(lái)設(shè)置要更改的path信息

    image

路由的懶加載

懶加載也叫延遲加載,即在需要的時(shí)候進(jìn)行加載喻奥,隨用隨載席纽。在單頁(yè)應(yīng)用中,如果沒(méi)有應(yīng)用懶加載撞蚕,運(yùn)用webpack打包后的文件將會(huì)異常的大润梯,造成進(jìn)入首頁(yè)時(shí),需要加載的內(nèi)容過(guò)多甥厦,延時(shí)過(guò)長(zhǎng)纺铭,會(huì)出現(xiàn)長(zhǎng)時(shí)間的白屏,即使做了loading也是不利于用戶體驗(yàn)刀疙,而運(yùn)用懶加載則可以將頁(yè)面進(jìn)行劃分舶赔,需要的時(shí)候加載頁(yè)面,可以有效的分擔(dān)首頁(yè)所承擔(dān)的加載壓力谦秧,減少首頁(yè)加載用時(shí)竟纳。簡(jiǎn)單的說(shuō)就是:進(jìn)入首頁(yè)時(shí)不用一次加載過(guò)多資源,造成頁(yè)面加載用時(shí)過(guò)長(zhǎng)疚鲤。

懶加載寫法:

// 路由的懶加載方式
    { path :"/home",component:()=>import("../views/Home")},// 當(dāng)我訪問(wèn)/home首頁(yè)時(shí)锥累,頁(yè)面才去加載Home組件,減少首頁(yè)加載的時(shí)長(zhǎng)
    { path :"/list",component:()=>import("../views/List")},
    { path :"/mine",component:()=>import("../views/Mine")}

非按需加載則會(huì)把所有的路由組件塊的js包打在一起石咬。當(dāng)業(yè)務(wù)包很大的時(shí)候建議用路由的按需加載(懶加載)揩悄。 按需加載會(huì)在頁(yè)面第一次請(qǐng)求的時(shí)候,把相關(guān)路由組件塊的js添加上鬼悠。

二級(jí)路由(路由嵌套)

在創(chuàng)建路由表的時(shí)候,可以為每一個(gè)路由對(duì)象創(chuàng)建children屬性亏娜,值為數(shù)組焕窝,在這個(gè)里面又可以配置一些路由對(duì)象來(lái)使用多級(jí)路由,注意:一級(jí)路由path前加'/'维贺,二級(jí)路由前不需要加'/'它掂。

{ path :"/list",component:()=>import("../views/List"),children:[
       // 二級(jí)路由前不需要加“/”
      { path: "audio", component: () => import("../views/Audio") },
      { path: "video", component: () => import("../views/Video") }
    ]}

二級(jí)路由組件的切換位置依然由router-view來(lái)指定(指定在父級(jí)路由組件的模板中)。

在List.vue中通過(guò)<router-view>來(lái)確定二級(jí)路由組件的位置。

<div>
      <router-link to = "/list/audio">音頻</router-link>
      <router-link to = "/list/video">視頻</router-link>
    </div>
    <router-view></router-view> 

二級(jí)路由切換效果:

image

router-link

<router-link> 組件支持用戶在具有路由功能的應(yīng)用中(點(diǎn)擊)導(dǎo)航虐秋。 通過(guò) to 屬性指定目標(biāo)地址榕茧,默認(rèn)渲染成帶有正確鏈接的 標(biāo)簽,可以通過(guò)配置 tag 屬性生成別的標(biāo)簽客给。另外用押,當(dāng)目標(biāo)路由成功激活時(shí),鏈接元素自動(dòng)設(shè)置一個(gè)表示激活的 CSS 類名靶剑。

to

router-link的to屬性蜻拨,默認(rèn)寫的是path(路由的路徑),可以通過(guò)設(shè)置一個(gè)對(duì)象桩引,來(lái)匹配更多缎讼。

<router-link tag = "li" :to = "{name:'detail',params:{id:'1'},query:{title:'最近播放'}}">我的歌單</router-link>

name

name是要跳轉(zhuǎn)的路由的名字,也可以寫path來(lái)指定路徑坑匠,但是用path的時(shí)候就不能使用params傳參血崭,params是傳路由參數(shù),query傳queryString參數(shù)厘灼。

replace

路由跳轉(zhuǎn)到不同的url默認(rèn)是push的過(guò)程功氨,當(dāng)用戶點(diǎn)擊瀏覽器后退按鈕式時(shí),則回到之前url手幢,replace屬性可以控制router-link的跳轉(zhuǎn)不被記錄捷凄。

依次點(diǎn)擊首頁(yè)——列表——音頻——視頻——我的,點(diǎn)擊返回按鈕時(shí)围来,依次返回之前的url跺涤。

image

在List.vue的<router-link>標(biāo)簽中添加replace屬性,則該標(biāo)簽內(nèi)的跳轉(zhuǎn)不會(huì)被記錄

<router-link
        v-for = "nav in navs"
        :key = "nav.id"
        :to = "{name:nav.name}"
        active-class = "title"
        replace
      >
        {{nav.title}}
      </router-link>

再依次點(diǎn)擊首頁(yè)——列表——音頻——視頻——我的监透,點(diǎn)擊返回按鈕時(shí)桶错,可以看到從音頻——視頻之間的跳轉(zhuǎn)沒(méi)有被記錄。

image

active-class

<router-link>且會(huì)根據(jù)當(dāng)前路由的變化為a標(biāo)簽添加對(duì)應(yīng)的router-link-active/router-link-exact-active(完全匹配成功)類名胀蛮,我們可以通過(guò)它來(lái)為標(biāo)簽設(shè)置不同的選中樣式院刁。

<style lang="scss">
.router-link-active{
    color:blue;
  }
  .router-link-exact-active{
    color:red;
    font-weight:900;
  }
</style>

標(biāo)簽切換時(shí),選中狀態(tài)的顯示效果:

image

還可以通過(guò)<router-link>的active-class屬性給a標(biāo)簽添加指定一個(gè)activeClass名粪狼,通過(guò)設(shè)置這個(gè)class的樣式退腥,來(lái)設(shè)置標(biāo)簽選中時(shí)的狀態(tài),功能類似于router-link-exact-active再榄。

<router-link
        v-for = "nav in navs"
        :key = "nav.id"
        :to = "nav.path"
        active-class = "title"
      >
        {{nav.title}}
      </router-link>

設(shè)置.title樣式

<style lang = "scss" scoped>
  .title{
    color:aquamarine;
  }
</style>

顯示效果:

image

tag

<router-link>默認(rèn)渲染成帶有正確鏈接的a標(biāo)簽狡刘,可以通過(guò)配置 tag 屬性生成別的標(biāo)簽。

<ul>
      <router-link tag = "li">我的歌單</router-link>
      <router-link tag = "li">最近播放</router-link>
    </ul>
image

參數(shù)傳遞

有的時(shí)候我們需要在路由跳轉(zhuǎn)的時(shí)候跟上參數(shù)困鸥,路由傳參的參數(shù)主要有兩種:路由參數(shù)嗅蔬、queryString參數(shù)。

路由參數(shù)

在router路由表中配置動(dòng)態(tài)路由,下面的代碼就是給detail路由配置接收id的參數(shù)澜术,多個(gè)參數(shù)繼續(xù)在后面設(shè)置艺蝴。

// 配置動(dòng)態(tài)路由
    { path:"/detail/:id",component:()=>import("../views/Detail.vue")}

在頁(yè)面中通過(guò)<router-link>的to屬性傳遞參數(shù):

<ul>
      <router-link tag = "li" to = "/detail/1">我的歌單</router-link>
      <router-link tag = "li" to = "/detail/2">最近播放</router-link>
    </ul>

在Detail.vue中打印this.$route.params.id

export default {
    created(){
        //獲取動(dòng)態(tài)路由傳遞過(guò)來(lái)的參數(shù)
        console.log(this.$route.params.id)
    }
}

在頁(yè)面中通過(guò)$route.params.id渲染獲取到的動(dòng)態(tài)id

<template>
    <div class = "detail">
        我是詳情頁(yè),我的動(dòng)態(tài)id是:{{$route.params.id}}
    </div>
</template>
image

queryString參數(shù)

queryString參數(shù)不需要在路由表設(shè)置接收,直接設(shè)置鸟废?后面的內(nèi)容:

<ul>
      <router-link tag = "li" to = "/detail/1?title=我的歌單">我的歌單</router-link>
      <router-link tag = "li" to = "/detail/2?title=最近播放">最近播放</router-link>
    </ul>

在路由組件中通過(guò)this.$route.query接收

export default {
    created(){
        //獲取動(dòng)態(tài)路由傳遞過(guò)來(lái)的參數(shù)
        console.log(this.$route.params.id,this.$route.query.title)
    }
}

打印結(jié)果:

image

頁(yè)面渲染效果:

image

上面的參數(shù)傳遞也可以寫成對(duì)象的形式:

<!-- 寫成對(duì)象的形式 -->
      <router-link tag = "li" :to = "{path:'/detail/2',query:{title:'最近播放'}}">最近播放</router-link>

通過(guò)prop將路由與組件解耦

在組件中接收路由參數(shù)需要this.$route.params.id猜敢,代碼冗余,現(xiàn)在可以在路由表里配置props:true侮攀。

{ path:"/detail/:id",component:()=>import("../views/Detail.vue"),name:"detail",props:true}

在路由組件中可以通過(guò)props接收id參數(shù)去使用

props:["id"],

在頁(yè)面中就可以通過(guò){{id}}的方式來(lái)使用路由傳遞的參數(shù)

我的動(dòng)態(tài)id是:{{id}}

默認(rèn)路由和重定向

默認(rèn)路由

當(dāng)我們進(jìn)入應(yīng)用锣枝,默認(rèn)想顯示某一個(gè)路由組件,或者當(dāng)我們進(jìn)入某一級(jí)路由組件的時(shí)候想默認(rèn)顯示其某一個(gè)子路由組件兰英,我們可以配置默認(rèn)路由撇叁。

設(shè)置當(dāng)用戶訪問(wèn)"/list"的時(shí)候默認(rèn)顯示"/list/audio"界面

{ path :"/list",component:()=>import("../views/List"),children:[
       // 二級(jí)路由前不需要加“/”
      { path :"",redirect:"audio"},
      { path: "audio", component: () => import("../views/Audio") },
      { path: "video", component: () => import("../views/Video") }
    ]}
image

重定向

有時(shí)候雖然當(dāng)前url與路由表不匹配,但是我們希望跳轉(zhuǎn)到同一個(gè)頁(yè)面或者說(shuō)是打開(kāi)同一個(gè)組件畦贸,這時(shí)候我們就需要使用redirect參數(shù)重定向到其他路由陨闹。

如果我們直接寫成如下形式:

{ path: "/", component: () => import("../views/Home")},

雖然當(dāng)我們?cè)L問(wèn)"/"的時(shí)候可以顯示"/home"頁(yè)面,但是可以看到標(biāo)簽上并沒(méi)有添加router-link-exact-active的class名薄坏,所以無(wú)法顯示選中的樣式趋厉。

image

我們需要寫成路由重定向形式:

//路由重定向
    { path :'/',redirect:"/home"}

當(dāng)我們?cè)诘刂窓谠L問(wèn)"/"的時(shí)候會(huì)自動(dòng)跳轉(zhuǎn)到"/home"頁(yè)面,并且標(biāo)簽可以顯示選中樣式胶坠。

image

命名路由

我們可以給路由對(duì)象配置name屬性君账,這樣的話,我們?cè)谔D(zhuǎn)的時(shí)候直接寫"name:名稱"就會(huì)快速的找到此name屬性對(duì)應(yīng)的路由沈善,不需要寫大量的urlpath路徑了乡数。

將之前配置的路由添加name屬性:

{ path: "audio", component: () => import("../views/Audio"),name:"audio"},
{ path: "video", component: () => import("../views/Video"),name: "video"}

在List.vue的data中將path改為name屬性:

data(){
    return{
      navs:[
        /* {id:1,title:"音頻",path:"/list/audio"},
        {id:2,title:"視頻",path:"/list/video"} */
        {id:1,title:"音頻",name:"audio"},
        {id:2,title:"視頻",name:"video"}
      ]
    }
  }

將<router-link>中的to屬性改為"name:名稱"形式

<router-link
        v-for = "nav in navs"
        :key = "nav.id"
        :to = "{name:nav.name}"
        active-class = "title"
      >
        {{nav.title}}
      </router-link>

可以看到實(shí)現(xiàn)效果是完全相同的:

image

給detail也添加一個(gè)name屬性

{ path:"/detail/:id",component:()=>import("../views/Detail.vue"),name:"detail"}

Home.vue中的<router-link>可以改寫成如下格式:

<router-link tag = "li" :to = "{name:'detail',params:{id:'1'},query:{title:'最近播放'}}">我的歌單</router-link>

params傳遞的參數(shù)通過(guò)this.$route.parmas.id來(lái)獲取

query傳遞的參數(shù)通過(guò)this.$route.query.title來(lái)獲取

編程式導(dǎo)航

<router-link>可以讓我們直接跳轉(zhuǎn)頁(yè)面,但是有的時(shí)候需要在跳轉(zhuǎn)前進(jìn)行一些動(dòng)作闻牡,這時(shí)候我們可以方法里使用$router的方法净赴。

當(dāng)我們想在Mine我的頁(yè)面添加一個(gè)點(diǎn)擊返回首頁(yè)的鏈接時(shí),可以通過(guò)<router-link>標(biāo)簽來(lái)實(shí)現(xiàn):

<div class="home">
    <router-link to = "/">mine我的</router-link>
  </div>
image

也可以通過(guò)編程式導(dǎo)航來(lái)實(shí)現(xiàn)罩润,在頁(yè)面中添加一個(gè)button按鈕玖翅,給按鈕添加一個(gè)點(diǎn)擊事件clickMe

<button @click = "clickMe">點(diǎn)擊返回首頁(yè)</button>

在method中編寫clickMe方法站削,通過(guò)$router的push方法暖眼,讓它跳轉(zhuǎn)到"/"頁(yè)面

methods:{
    clickMe(){
      let flag = confirm("是否返回首頁(yè)")
      if(flag){
        // 編程式導(dǎo)航
        this.$router.push("/");
      }
    }
  }
image

路由模式

為了構(gòu)建SPA(單頁(yè)面應(yīng)用)频敛,需要引入前端路由系統(tǒng)箩朴,這也就是Vue-router存在的意義。前端路由的核心舀瓢,就在于:改變視圖的同時(shí)不會(huì)向后端發(fā)出請(qǐng)求园担。

hash和history這兩個(gè)方法應(yīng)用于瀏覽器的歷史記錄站旨椒,在當(dāng)前已有的back祝峻、forward、go 的基礎(chǔ)之上,它們提供了對(duì)歷史記錄進(jìn)行修改的功能莱找。只是當(dāng)它們執(zhí)行修改是酬姆,雖然改變了當(dāng)前的URL,但你瀏覽器不會(huì)立即向后端發(fā)送請(qǐng)求奥溺。

hash:即地址欄URL中的#符號(hào)(此hsah 不是密碼學(xué)里的散列運(yùn)算)

路由有兩種模式:hash辞色、history,默認(rèn)會(huì)使用hash模式

image

比如這個(gè)URL:http://www.baidu.com/#/hello, hash 的值為#/hello浮定。它的特點(diǎn)在于:hash 雖然出現(xiàn)URL中相满,但不會(huì)被包含在HTTP請(qǐng)求中,對(duì)后端完全沒(méi)有影響桦卒,因此改變hash不會(huì)重新加載頁(yè)面立美。

history:利用了HTML5 History Interface 中新增的pushState() 和replaceState() 方法。(需要特定瀏覽器支持)

如果url里不想出現(xiàn)丑陋hash值(#)方灾,在new VueRouter的時(shí)候配置mode值為history來(lái)改變路由模式建蹄,本質(zhì)使用H5的histroy.pushState方法來(lái)更改url,不會(huì)引起刷新裕偿。

// 默認(rèn)會(huì)使用hash模式
  mode:"history",

image

history模式洞慎,會(huì)出現(xiàn)404 的情況,需要后臺(tái)配置嘿棘。

404錯(cuò)誤

  1. hash模式下劲腿,僅hash符號(hào)之前的內(nèi)容會(huì)被包含在請(qǐng)求中,當(dāng)用戶訪問(wèn)https://www.baidu.com/#/home時(shí)實(shí)際請(qǐng)求的是:https://www.baidu.com/鸟妙。因此對(duì)于后端來(lái)說(shuō)焦人,即使沒(méi)有做到對(duì)路由的全覆蓋,頁(yè)面也不會(huì)返回404錯(cuò)誤圆仔;

    image

  2. history模式下垃瞧,前端的url必須和實(shí)際向后端發(fā)起請(qǐng)求的url 一致,因?yàn)槲覀兊膽?yīng)用是個(gè)單頁(yè)客戶端應(yīng)用坪郭,如果后臺(tái)沒(méi)有正確的配置个从,當(dāng)用戶在瀏覽器直接訪問(wèn) https://www.baidu.com/home/detail,缺少對(duì)/home/detail的路由處理歪沃,就會(huì)返回 404錯(cuò)誤嗦锐,這就不好看了。

    image

所以呢沪曙,你要在服務(wù)端增加一個(gè)覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態(tài)資源奕污,則應(yīng)該返回同一個(gè) index.html 頁(yè)面,這個(gè)頁(yè)面就是你 app 依賴的頁(yè)面液走。

導(dǎo)航守衛(wèi)(路由鉤子/路由守衛(wèi)/路由生命周期)

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

在某些情況下,當(dāng)路由跳轉(zhuǎn)前或跳轉(zhuǎn)后该抒、進(jìn)入慌洪、離開(kāi)某一個(gè)路由前、后凑保,需要做某些操作冈爹,就可以使用路由鉤子來(lái)監(jiān)聽(tīng)路由的變化。

全局守衛(wèi)

全局前置守衛(wèi)beforeEach

當(dāng)一個(gè)導(dǎo)航觸發(fā)時(shí)欧引,全局前置守衛(wèi)按照創(chuàng)建順序調(diào)用频伤。守衛(wèi)是異步解析執(zhí)行,此時(shí)導(dǎo)航在所有守衛(wèi) resolve 完之前一直處于 等待中维咸,所以頁(yè)面不會(huì)加載任何內(nèi)容剂买。

image

一定要在路由守衛(wèi)中調(diào)用next()方法來(lái)resolve這個(gè)鉤子

// 全局前置路由
router.beforeEach((to,from,next)=>{
  console.log("beforeEach:全局前置守衛(wèi)")
  // 一定要調(diào)用next()方法來(lái)resolve這個(gè)鉤子
  next();
})
image

每個(gè)守衛(wèi)方法接收三個(gè)參數(shù):

  • to: Route: 即將要進(jìn)入的目標(biāo)路由對(duì)象

  • from: Route: 當(dāng)前導(dǎo)航正要離開(kāi)的路由

    // 全局前置路由
    router.beforeEach((to,from,next)=>{
      console.log("beforeEach:全局前置守衛(wèi)")
      if(to.path === "/mine") {
        alert("即將進(jìn)入mine我的頁(yè)面")
      }
      if(from.path === "/home"){
        alert("從首頁(yè)離開(kāi)")
      }
      // 一定要調(diào)用next()方法來(lái)resolve這個(gè)鉤子
      next();
    })
    
    image
  • next: Function: 一定要調(diào)用該方法來(lái) resolve 這個(gè)鉤子。執(zhí)行效果依賴 next 方法的調(diào)用參數(shù)癌蓖。

    • next(): 進(jìn)行管道中的下一個(gè)鉤子瞬哼。如果全部鉤子執(zhí)行完了,則導(dǎo)航的狀態(tài)就是 confirmed (確認(rèn)的)租副。
    • next(false): 中斷當(dāng)前的導(dǎo)航坐慰。如果瀏覽器的 URL 改變了 (可能是用戶手動(dòng)或者瀏覽器后退按鈕),那么 URL 地址會(huì)重置到 from 路由對(duì)應(yīng)的地址用僧。
    • next('/') 或者 next({ path: '/' }): 跳轉(zhuǎn)到一個(gè)不同的地址结胀。當(dāng)前的導(dǎo)航被中斷,然后進(jìn)行一個(gè)新的導(dǎo)航责循。你可以向 next 傳遞任意位置對(duì)象糟港,且允許設(shè)置諸如 replace: truename: 'home' 之類的選項(xiàng)以及任何用在 router-linkto prop或 router.push 中的選項(xiàng)院仿。
    • next(error): (2.4.0+) 如果傳入 next 的參數(shù)是一個(gè) Error 實(shí)例秸抚,則導(dǎo)航會(huì)被終止且該錯(cuò)誤會(huì)被傳遞給 router.onError()注冊(cè)過(guò)的回調(diào)。

確保要調(diào)用 next 方法歹垫,否則鉤子就不會(huì)被 resolved剥汤。

全局后置鉤子afterEach

也可以注冊(cè)全局后置鉤子,然而和前置守衛(wèi)不同的是排惨,這些鉤子不會(huì)接受 next 函數(shù)也不會(huì)改變導(dǎo)航本身:

// 全局后置鉤子
router.afterEach((to,from)=>{
  if (to.path === "/list/audio") {
    alert("已經(jīng)進(jìn)入list列表audio頁(yè)面")
  }
})
image

局部守衛(wèi)

路由獨(dú)享的守衛(wèi)

在路由配置上直接定義beforeEnter守衛(wèi):

{ path :"/mine",component:()=>import("../views/Mine"),beforeEnter(to,from,next){
      console.log("進(jìn)入到mine頁(yè)面了")
      next();
    }}
image
組件內(nèi)的守衛(wèi)

最后吭敢,你可以在路由組件內(nèi)直接定義以下路由導(dǎo)航守衛(wèi):

  1. beforeRouteEnter

    在進(jìn)入該組件之前執(zhí)行,該路由守衛(wèi)中獲取不到實(shí)例this暮芭,因?yàn)榇藭r(shí)組件實(shí)例還沒(méi)被創(chuàng)建鹿驼。beforeRouteEnter 守衛(wèi) 不能 訪問(wèn) this欲低,因?yàn)槭匦l(wèi)在導(dǎo)航確認(rèn)前被調(diào)用,因此即將登場(chǎng)的新組件還沒(méi)被創(chuàng)建。

    在Home.vue中添加beforeRouteEnter:

    beforeRouteEnter(to,from,next){
        console.log("beforeRouteEnter:進(jìn)入組件之前",this)
        next()
      }
    

    打印this蠢沿,顯示undefined

    image

    不過(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)有必要了匈子。

  1. beforeRouteLeave

    在離開(kāi)該組件之前執(zhí)行,該路由守衛(wèi)中可以訪問(wèn)組件實(shí)例"this"闯袒。

    在Home.vue中添加beforeRouteLeave:

      beforeRouteLeave(to,from,next){
        console.log("beforeRouteLeave:離開(kāi)組件之前",this)
        next()
      }
    

    此時(shí)可以打印組件實(shí)例"this"

    image

    這個(gè)離開(kāi)守衛(wèi)通常用來(lái)禁止用戶在還未保存修改前突然離開(kāi)虎敦。該導(dǎo)航可以通過(guò) next(false) 來(lái)取消。

  1. beforeRouteUpdate(2.2 新增)

    當(dāng)一個(gè)組件被重復(fù)調(diào)用的時(shí)候執(zhí)行該守衛(wèi)

    在Deatil.vue中添加beforeRouteUpdate:

        beforeRouteUpdate(to,from,next){
            console.log("beforeRouteUpdate")
            next()
        }
    
    image
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末政敢,一起剝皮案震驚了整個(gè)濱河市其徙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌喷户,老刑警劉巖唾那,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異褪尝,居然都是意外死亡闹获,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門河哑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)避诽,“玉大人,你說(shuō)我怎么就攤上這事璃谨∩陈” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵睬罗,是天一觀的道長(zhǎng)轨功。 經(jīng)常有香客問(wèn)我,道長(zhǎng)容达,這世上最難降的妖魔是什么古涧? 我笑而不...
    開(kāi)封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮花盐,結(jié)果婚禮上羡滑,老公的妹妹穿的比我還像新娘菇爪。我一直安慰自己,他們只是感情好柒昏,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布凳宙。 她就那樣靜靜地躺著,像睡著了一般职祷。 火紅的嫁衣襯著肌膚如雪氏涩。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天有梆,我揣著相機(jī)與錄音是尖,去河邊找鬼。 笑死泥耀,一個(gè)胖子當(dāng)著我的面吹牛饺汹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播痰催,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼兜辞,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了夸溶?” 一聲冷哼從身側(cè)響起逸吵,我...
    開(kāi)封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蜘醋,沒(méi)想到半個(gè)月后胁塞,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡压语,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年啸罢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胎食。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡扰才,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出厕怜,到底是詐尸還是另有隱情衩匣,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布粥航,位于F島的核電站琅捏,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏递雀。R本人自食惡果不足惜柄延,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望缀程。 院中可真熱鬧搜吧,春花似錦市俊、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蜒程,卻和暖如春绅你,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背搞糕。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工勇吊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人窍仰。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像礼殊,于是被迫代替她去往敵國(guó)和親驹吮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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