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)
-
如果不是使用腳手架創(chuàng)建的項(xiàng)目证膨,需要手動(dòng)安裝vue-router路由模塊如输。
cnpm install vue-router -S
-
引入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屬性脖祈。
-
創(chuàng)建router路由器肆捕,并導(dǎo)出。
let router = new Router({ routes:[ ] }) export default router;
-
在根實(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盖高。
-
創(chuàng)建router路由表
let router = new Router({ routes:[ { path:"/home",component:Home }, { path: "/list", component: List }, { path: "/mine", component: Mine } ] })
-
在App.vue中利用router-view來(lái)指定路由切換的位置
<template> <div id="app"> Hello app.vue! <!-- 顯示路由組件的位置 --> <router-view></router-view> </div> </template>
路由切換效果:
-
使用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>
<router-link>會(huì)渲染成a標(biāo)簽慎陵,添加to屬性來(lái)設(shè)置要更改的path信息
路由的懶加載
懶加載也叫延遲加載,即在需要的時(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í)路由切換效果:
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跺涤。
在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)有被記錄。
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)的顯示效果:
還可以通過(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>
顯示效果:
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>
參數(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>
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é)果:
頁(yè)面渲染效果:
上面的參數(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") }
]}
重定向
有時(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ú)法顯示選中的樣式趋厉。
我們需要寫成路由重定向形式:
//路由重定向
{ path :'/',redirect:"/home"}
當(dāng)我們?cè)诘刂窓谠L問(wèn)"/"的時(shí)候會(huì)自動(dòng)跳轉(zhuǎn)到"/home"頁(yè)面,并且標(biāo)簽可以顯示選中樣式胶坠。
命名路由
我們可以給路由對(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)效果是完全相同的:
給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>
也可以通過(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("/");
}
}
}
路由模式
為了構(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模式
比如這個(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",
history模式洞慎,會(huì)出現(xiàn)404 的情況,需要后臺(tái)配置嘿棘。
404錯(cuò)誤
-
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ò)誤圆仔;
-
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ò)誤嗦锐,這就不好看了。
所以呢沪曙,你要在服務(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)容剂买。
一定要在路由守衛(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();
})
每個(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(); })
-
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: true
、name: 'home'
之類的選項(xiàng)以及任何用在router-link
的to
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è)面")
}
})
局部守衛(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();
}}
組件內(nèi)的守衛(wèi)
最后吭敢,你可以在路由組件內(nèi)直接定義以下路由導(dǎo)航守衛(wèi):
-
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
不過(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ì)于beforeRouteUpdate
和beforeRouteLeave
來(lái)說(shuō)野宜,this
已經(jīng)可用了,所以不支持傳遞回調(diào)魔策,因?yàn)闆](méi)有必要了匈子。
-
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"
這個(gè)離開(kāi)守衛(wèi)通常用來(lái)禁止用戶在還未保存修改前突然離開(kāi)虎敦。該導(dǎo)航可以通過(guò)
next(false)
來(lái)取消。
-
beforeRouteUpdate(2.2 新增)
當(dāng)一個(gè)組件被重復(fù)調(diào)用的時(shí)候執(zhí)行該守衛(wèi)
在Deatil.vue中添加beforeRouteUpdate:
beforeRouteUpdate(to,from,next){ console.log("beforeRouteUpdate") next() }