概念
路由器 router,整個應用共用一個路由器屬性$router
路由 route恭应,每個路由組件都有獨立的路由屬性$route
普通組件:路由沒配置的組件
路由組件:路由配置的組件
標簽
<router-link class="" to="/path" ></router-link> 默認會被渲染成一個a標簽,阻止默認頁面跳轉行為斜筐。
to還可以傳對象棉姐,包裝path朱监、name、params鸵赖、query等,具體可以參考文檔拄衰。
<router-view></router-view>路由組件會被渲染到這里
目錄結構
普通組件放在components目錄中
路由組件放在pages目錄中
路由導航
除了上述提到的標簽式路由導航它褪,還有編程式路由導航。
例如:
this.$router.push({path:'/user/detail', query:{...}})
this.$router.replace({path:'/user/detail', query:{...}})push比較適合大的分類路由切換翘悉,基本就是切換業(yè)務場景了
replace比較適合細小的路由切換茫打,比如當前業(yè)務場景下的子品類切換等
這樣回退的時候可以一次回到上一個業(yè)務場景頁面
路由組件
路由切換的時候,路由組件會被掛載妖混,之前的路由組件默認會被銷毀老赤。可以用<keep-alive>包裹路由組件制市,緩存替代銷毀抬旺。
路由組件獲取值的方式:
- 組件內(nèi)直接this.$route.query獲取
- 組件內(nèi)直接this.$route.params獲取
- 比較推薦的是query傳參,路由路徑配置比較清晰祥楣,然后通過配置路由對象內(nèi)的props屬性嚷狞,給路由組件以props形式傳參
// 子路由配置中 children[ { name: 'aaa', path: 'detail', // 子路由路徑開頭不要加“/” component: Detail, props($route) { return { id: $route.query.id, title: $route.query.title } } } ]
對應的路由組件Detail只需要配置下props:['id', 'title']就可以在模板中方便使用了块促。
這樣寫的優(yōu)點是路由配置相關都集中在一起,組件編碼獲取參數(shù)也不需要獲取$route床未,各自分工明確竭翠,聚合性比較好。
利用緩存
<!--name屬性指定的是組件名薇搁,指定緩存內(nèi)容區(qū)的某個組件-->
<keep-alive name="formItemName">
<router-view></router-view>
</keep-alive>
使用keep-alive比較適合類似表單頁簽切換的場景斋扰,再配合$router.replace(),可以提高用戶體驗啃洋。
生命周期鉤子:actived 和 deactived
actived:被 keep-alive 緩存的組件激活時調(diào)用传货。
deactived:被 keep-alive 緩存的組件失活時調(diào)用。
以上2個鉤子需要配合keepalive標簽使用宏娄。如果被緩存的組件已經(jīng)隱藏了问裕,有些行為例如setInterval等timer計時器的行為(或者其他定制業(yè)務行為)并不需要繼續(xù)執(zhí)行,可以考慮在actived和deactived鉤子中加以控制孵坚。
actived() {
this.timer = setInterval(() => {
// ...
})
},
deactived() {
clearInterval(this.timer)
}
路由導航守衛(wèi)
以下是路由守衛(wèi)觸發(fā)全流程粮宛,可以根據(jù)業(yè)務需求配置。
- 導航被觸發(fā)卖宠。
- 在失活的組件里調(diào)用 beforeRouteLeave 守衛(wèi)巍杈。
- 調(diào)用全局的 beforeEach 守衛(wèi)。(router上配置)
- 在重用的組件里調(diào)用 beforeRouteUpdate 守衛(wèi) (2.2+)扛伍。
- 在路由配置里調(diào)用 beforeEnter筷畦。
- 解析異步路由組件。
- 在被激活的組件里調(diào)用 beforeRouteEnter刺洒。
- 調(diào)用全局的 beforeResolve 守衛(wèi) (2.5+)鳖宾。
- 導航被確認。
- 調(diào)用全局的 afterEach 鉤子逆航。
- 觸發(fā) DOM 更新攘滩。
- 調(diào)用 beforeRouteEnter 守衛(wèi)中傳給 next 的回調(diào)函數(shù),創(chuàng)建好的組件實例會作為回調(diào)函數(shù)的參數(shù)傳入纸泡。
瀏覽器hash模式和history模式
hash模式的地址欄會有一個”#“漂问,后面跟各種路由路徑和參數(shù),此模式下瀏覽器不會將”#“和之后的內(nèi)容發(fā)給服務器女揭,也就是服務收到的請求地址只是”#“之前的部分蚤假。
因此如果前端使用了history模式,還想正常訪問頁面吧兔,就得需要后端(或者nginx)對請求的地址進行攔截處理磷仰。
例如nodejs可以npm安裝connect-history-api-fallback
// 服務端項目
npm install connect-history-api-fallback
服務端處理請求代碼(nodejs express)
const express = require('express')
const histroy = require('connect-history-api-fallback')
const app = express() // 創(chuàng)建一個服務
app.use(history()) // 注冊history插件,可以根據(jù)history規(guī)則拆分請求地址
app.use(express.static(__dirname+'/static')) // 注冊靜態(tài)資源地址境蔼,這樣就可以到前端頁面了
// 配置接口
app.get('/user', (req, res) => {
req.send({
id: '001',
name: 'zhangsan'
})
})
app.listen(5000, err => {
if (!err) console.log('服務啟動成功灶平,端口:5000')
})
除了nodejs伺通,我們還可以使用nginx進行反向代理,需要自己配置好正則規(guī)則
還可以使用java逢享,也有專門的庫支持history模式地址截取呼巴。
hash和history相比儡嘶,hash的兼容性略好一點鳞溉。vue-router默認使用的是”hash“模式蜀变,如果想改成history模式,需要把router的mode配置改成”history“侧但。
vue-router的原理
理論基礎
瀏覽器地址的改變會觸發(fā)popstate事件矢空;瀏覽器地址hash(#后面的部分)的改變會觸發(fā)hashchange事件。這讓我們可以監(jiān)控到當前路由的變化禀横;調(diào)用瀏覽器的api pushState或者js直接改變location.hash并不會觸發(fā)頁面跳轉屁药,只是地址欄地址發(fā)生了變化,這讓我們可以實現(xiàn)api讓瀏覽器地址改變柏锄。
基于上述特性酿箭,VueRouter向Vue注入組件后,就可以實現(xiàn)根據(jù)路由變化讓Vue重新加載指定組件了绢彤。這就是所謂的路由跳轉。
-
一是根據(jù)配置的模式(hash還是history)給window加事件監(jiān)聽(popstate或者hashchange)
-
使用vue插件+mixin的方式蜓耻,在beforeCreate()鉤子里茫舶,往VueComponent實例上加了一個_route屬性,用于存放當前路由對象刹淌,并且對此屬性加了數(shù)據(jù)代理饶氏,地址變化會同步這里的屬性。
RouterView組件發(fā)現(xiàn)當前路由改變的時候(通過vue的數(shù)據(jù)代理)有勾,就會根據(jù)配置去加載指定的vueComponent從而實現(xiàn)了界面切換效果