摘要:由命名路由與子路由構(gòu)成整體結(jié)構(gòu),我們用它構(gòu)建如下頁面。以下兩張圖說明路由和子路由是如何工作的。繼續(xù)修改好友信息的路由部分添加好友信息為組件添加動態(tài)路由為動態(tài)路由添加為路徑參數(shù)添加數(shù)據(jù)下發(fā)為組件添加,并使用它。
不使用vue-router的情況
代碼
官方給出下面的例子在不使用vue-router的情況下來實現(xiàn)一個路由。
該示例結(jié)合了H5歷史管理API、單文件組件、JS模塊相關(guān)內(nèi)容來實現(xiàn)路由
后面說的頁面只是一條瀏覽器歷史記錄,關(guān)于歷史記錄管理見歷史記錄管理(window.history)
simple_router.js為入口,進行組件的加載,和其他一些功能初始化工作。
//simple_router.js data: { currentRoute: window.location.pathname }, computed: { ViewComponent() { const matchingView = routes[this.currentRoute] return matchingView ? require("./pages/" + matchingView + ".vue").default : require("./pages/404.vue").default } }, render(h) { return h(this.ViewComponent) }
屬性currentRoute是一個狀態(tài)轉(zhuǎn)換器(在VLink.vue中改變狀態(tài)),在下層組件中通過改變它來隨時切換頁面。它在轉(zhuǎn)換頁面前,會去路由表中查找對應(yīng)的頁面路徑。
routes.js為路由表
//routes.js export default { "/":"Home", "/about":"About" }
每個路由的頁面都是一個組件,切換頁面就是在這些組件中切換。要來回切換這些組件需要先加載它們,我們在ViewComponent計算屬性中完成這個工作,通過currentRoute定位好對應(yīng)的組件,在通過require(組件路徑).default在運行時動態(tài)的加載它,并在渲染函數(shù)中使用它。
特別注意的是,如果你使用vue-loader@1.4+版本,這個require后面要加上default,否則報個加載模板失敗的錯誤,因為在這個版本及更高版本上,vue文件導(dǎo)出的全是esModule,而require加載的是commonjs格式的模塊,在這里具體就是它返回的是一個包含default的對象的對象。
具體查看vue-loader API esModule選項、ES6入門模塊部分、記升級vue-loader版本時遇到的一個坑
這里入口中最重要的是別忘了,使用window.onpopstate管理歷史記錄,激活后退按鈕的功能
window.addEventListener("popstate", () => { app.currentRoute = window.location.pathname })
之后就是定義需要切換的幾個組件,Home.vue、About.vue和404.vue,它們大同小異
Welcome home
這些組件通過Main.vue完成具體的布局
Home About
接著就是在Main.vue中使用子組件VLink.vue
VLink.vue很也是很關(guān)鍵,定義了一個鏈接,在開始入口文件中的currentRoute 這個狀態(tài)轉(zhuǎn)換器,就是通過點擊鏈接改變狀態(tài)的,而這個改變值this.href是通過布局組件Main.vueProps數(shù)據(jù)下發(fā)下來的(
總結(jié)下就是 通過simple_router.js定義如何加載頁面(運行時動態(tài)加載),通過VLink.vue觸發(fā)這個加載,通過布局文件將這兩部分結(jié)合在一起。其中夾雜了歷史記錄的管理。使用vue-router的情況
該插件整體結(jié)構(gòu)比較簡單,而細節(jié)非常繁瑣(用來解決各種各樣的缺陷和bug)。
由命名路由與子路由構(gòu)成整體結(jié)構(gòu),我們用它構(gòu)建如下頁面。
目錄結(jié)構(gòu)如下
代碼在這vue-router v0.1
//router.js export default new VueRouter({ routes: [ { path: "/", component: Home }, { path: "/settings", component: UserSettings, children: [ { path: "userinfo", component:UserInfo }, { path: "useremail", component:UserEmail } ] }, { path: "/interaction", component: UserInteraction, children: [ { path: "userfriend", component: UserFriend }, { path: "userFollow", component: UserFollow} ] } ] })
頂層路由及其對應(yīng)的組件
vue-router 測試頁
第二層路由(子路由)及其對應(yīng)組件,這里。
以下兩張圖說明路由和子路由是如何工作的。
第一張圖說明當(dāng)我們點擊鏈接,經(jīng)過路由就可以把對應(yīng)的組件,放到頁面指定的
而第二張,就是對路由過程的補充,通過路由或子路由去尋找對應(yīng)組件,找到的組件再反過來放入視圖中。
命名路由有時候我們需要在一個組件中使用多塊
比如我們需要在用戶設(shè)置中的基本信息和更換郵箱中都加一段廣告。
增加一個廣告組件Advertisement.vue
某廣告
在UserSettings.vue中添加一段命名的
在路由文件中為命名的
//router.js //... children: [ { path: "userinfo", components: { default:UserInfo, //添加命名路由 adver:Advertisement } }, { path: "useremail", components: { default:UserEmail, //添加命名路由 adver:Advertisement } } ] //...
具體代碼 添加命名路由
為激活的鏈接添加樣式被激活的鏈接,vue-router會為其添加樣式類router-link-active,我們在這個class中可以為其添加具體樣式,上面代碼中已經(jīng)被添加了樣式。
a.router-link-active, li.router-link-active>a { background-color: gainsboro; color: #37C6C0; }
這里被分成兩種情況
當(dāng)這種不帶tag的寫法
用戶首頁
被解析成
帶tag的寫法
基本信息
被解析成
類router-link-active被添加在tag上。
細心的你可以發(fā)現(xiàn)不管哪個鏈接被激活,用戶首頁上始終存在著router-link-active,這是因為它的路由是/,所以在其他路由被解析時,/也會被匹配。我們可以用exact解決這個問題,它使路徑字符串要完全匹配。
動態(tài)路由模糊匹配用戶首頁
代碼 v0.3 動態(tài)路由匹配與Props屬性
有時候一堆同級路由它們所對應(yīng)的組件基本相同,我們就可以使用動態(tài)路由,匹配到同一個組件。
我們在我的好友中有一個好友列表。當(dāng)點擊某好友會顯示他的信息。
下面只使用了最簡單的匹配模式,關(guān)于更復(fù)雜的匹配,vue-router使用path-to-regexp動態(tài)匹配請求路徑,具體查看PocketLibs(2)—— 請求相關(guān) path-to-regexp
//router.js //...... { path: "/interaction", component: UserInteraction, children: [ { path: "userfriend", component: UserFriend, //添加好友信息 為組件FriendInfo添加動態(tài)路由 children: [ { path:"fd/:id",component:FriendInfo} ] }, { path: "userFollow", component: UserFollow} ] } //......
修改組件UserFriend.vue,添加好友列表與好友信息視圖
好友列表
好友{{item}}
添加好友信息組件FriendInfo.vue
使用命名組件和Props改進我的好友模塊好友{{$route.params.id}}信息
在剛才的代碼中,UserFriend.vue中有以下代碼
:to=""/interaction/userfriend/fd/" + item "有點違和。我們可以用命名路由改造一下。
先在路由文件中為用戶信息對應(yīng)的路由添加成name屬性,切換成命名路由。
//router.js { path: "userfriend", component: UserFriend, //添加好友信息 為組件FriendInfo添加動態(tài)路由 children: [ //為動態(tài)路由添加name { path:"fd/:id",name:"fd",component:FriendInfo} ] }
然后修改UserFriend.vue中的
好友{{item}}
效果與上面的一樣。
我們再仔細看看組件FriendInfo.vue
好友{{$route.params.id}}信息
在組件中使用 $route 會使之與其對應(yīng)路由形成高度耦合,從而使組件只能在某些特定的 URL 上使用,限制了其靈活性。我們可以為路徑參數(shù)添加Props數(shù)據(jù)下發(fā)。
繼續(xù)修改好友信息的路由部分
//router.js { path: "userfriend", component: UserFriend, //添加好友信息 為組件FriendInfo添加動態(tài)路由 children: [ //為動態(tài)路由添加name //為路徑參數(shù)添加Props數(shù)據(jù)下發(fā) { path:"fd/:id",name:"fd",component:FriendInfo,props:true} ] }
為組件FriendInfo添加Props,并使用它。
在路由中使用Props的其他模式好友{{id}}信息
如果在命名路由中使用Props數(shù)據(jù)下發(fā),要為每一個對應(yīng)組件,都設(shè)置Props。
{ path: "/user/:id", components: { default: User, sidebar: Sidebar }, props: { default: true, sidebar: false } }
Props還可以是一個對象
{ path:"fd/:id",name:"fd",component:FriendInfo,props:{id:1}}
還可以是一個函數(shù),函數(shù)接收一個$route對象
function dynamicPropsFn (route) { const now = new Date() return { name: (now.getFullYear() + parseInt(route.params.years)) + "!" } } //... { path: "/dynamic/:years", component: Hello, props: dynamicPropsFn }鉤子函數(shù)、請求數(shù)據(jù)和進度條
代碼 vue-router 0.4 鉤子、請求數(shù)據(jù)與全局進度條
我們使用axios發(fā)送請求,http://schematic-ipsum.heroku... 可以作為響應(yīng)模擬一些基本的數(shù)據(jù)。
改造好友信息組件FriendInfo.vue,我們在組件級鉤子beforeRouteUpdate中發(fā)送請求。
好友{{id}}信息
- 姓名:{{name}}
- 電話:{{phone}}
- 郵件:{{email}}
beforeRouteEnter鉤子中第三個參數(shù)next(),調(diào)用它時,才可以繼續(xù)其他操作(此時系統(tǒng)處于等待),我們在獲取到響應(yīng)時再調(diào)用它,因此在獲取響應(yīng)后才會看渲染效果。
仔細觀察可以發(fā)現(xiàn),多次查看好友信息,信息不會改變,查看控制臺發(fā)現(xiàn)beforeRouteEnter只調(diào)用了一次,只發(fā)送了一次信息。
首次查看信息時,解析路由并使組件FriendInfo激活,我們調(diào)用beforeRouteEnter,之后每次查看,組件不會重新被渲染,只會被重復(fù)利用,因此不會再調(diào)用beforeRouteEnter。注意該鉤子中不能使用this,因為在執(zhí)行它時組件還沒有被實例,但是next()的回調(diào)執(zhí)行時,組件已被實例,它接收組件實例作為參數(shù)(示例中的vm)
解決這個問題就靠beforeRouteUpdate,該鉤子在當(dāng)前路由改變,組件被復(fù)用時調(diào)用。比如從/interaction/userfriend/fd/1到/interaction/userfriend/fd/2時它就會調(diào)用。下面我們就在FriendInfo中添加這個鉤子。
beforeRouteUpdate(to, from, next) { axios.post("http://schematic-ipsum.herokuapp.com/", reqObject) .then(response => { this.name = response.data.name; this.phone = response.data.phone; this.email = response.data.email; next(); }); },
注意它是可以使用this的,它的next()不接收回調(diào)。
我們看下youtube
每次加載頁面會有個進度條
我們現(xiàn)在就使用全局鉤子函數(shù)和NProgress實現(xiàn)這個功能,在入口app.js文件中添加全局路由鉤子。
import Vue from "Vue" import nprogress from "nprogress" import "nprogress/nprogress.css" import router from "./router" const app = function () { //在任何導(dǎo)航被觸發(fā)前執(zhí)行 router.beforeEach((to, from, next) => { console.log("beforeEach") nprogress.start() next() }) //導(dǎo)航中的最后一個鉤子 router.afterEach((to, from) => { console.log("afterEach") nprogress.done() }) new Vue({ router, el: "#app" }) } export { app }給路由視圖添加動畫
代碼 vue-router 0.5 為
為顯示好友信息添加動畫
修改組件UserFriend
添加過渡類
.child-view { position: absolute; transition: all 1s cubic-bezier(.55,0,.1,1); } .slide-left-enter { opacity: 0; -webkit-transform: translate(60px, 0); transform: translate(60px, 0); } .slide-left-leave-active { opacity: 0; -webkit-transform: translate(-60px, 0); transform: translate(-60px, 0); }
由于在切換查看信息時,組件FriendInfo不會重新渲染,即除第一次外不會有動畫,因此需要設(shè)置key,這里有個不可預(yù)期的錯誤,即在
千萬不能這么做,key無法傳遞給FriendInfo的根節(jié)點。
我們需要在組件FriendInfo上設(shè)置key
//FriendInfo.vue重定向代碼 vue-router 0.6 重定向和別名
仿造我的好友,構(gòu)造關(guān)注的人當(dāng)點擊單數(shù)用戶時,顯示用戶信息,點擊雙數(shù)用戶時,顯示用戶被銷毀。
用戶信息為一個組件,銷毀為另一個組件。
路由配置如下:{ path: "userFollow", component: UserFollow, children: [ { path:"fw/:id", name:"fw", redirect: to => { if(to.params.id%2===0) return "fd/:id" else return "fi/:id" }, beforeEnter:(to, from, next) => { console.log(from) console.log(to) next() } }, { path:"fd/:id", component:UserDestroy, props:true }, { path:"fi/:id", component:FollowInfo, props:true } ] }每個routerLink的鏈接路徑為fw/:id,在redirect中配置重定向函數(shù),路徑參數(shù)id為單數(shù)重定向到路由fi/:id,雙數(shù)時,重定向到fd/:id。redirect還可以是個表示路由路徑的字符串或命名路由對象({name:"foo",params:{bar:"baz"}})。
另外在redirect屬性所在的路由中,導(dǎo)航守衛(wèi)不會執(zhí)行,如上面的beforeEnter不會執(zhí)行(全局的守衛(wèi)也不會執(zhí)行)。
別名我們增加一個頂級導(dǎo)航系統(tǒng)公告
為它添加路由
{ path: "/notification", component: SystemNotification }SystemNotification組件只是一個簡單的標題
系統(tǒng)公告
之后我想把這個頁面改成我的消息頁面
為此我們修改路由路徑/usermessage,將原來的名字配置為別名alias:"/notification",并保持routerLink的路徑不變。
這樣做一是其他網(wǎng)站引用該頁面不會產(chǎn)生404,二是路由內(nèi)部配置引用該路由也不會找不到。
{ path: "/usermessage", component: SystemNotification, alias:"/notification" },滾動行為代碼 vue-router 0.7 滾動行為
在我的消息中配置路由及其視圖,如下圖:配置4個路由及其對應(yīng)組件
我的消息
系統(tǒng)消息 好友消息 用戶組消息 其他消息 path: "/usermessage", component: SystemNotification, alias: "/notification", children: [ { path: "system-msg", component: SystemMessage, meta: { scrollToTop: false } }, { path: "friend-msg", component: FriendMessage, meta: { scrollToTop: true } }, { path: "group-msg", component: GroupMessage, meta: { scrollToTop: true } }, { path: "other-msg", component: OtherMessage, meta: { scrollToTop: true } } ]四個組件中定義一系列字符串列表。在其中插入下一個消息列表的routerLink,如
效果如下
使用歷史記錄回退時,保持原紀錄位置,是正常的。但點擊鏈接,跳到新頁面,也是原來位置,這不是我們預(yù)期的行為,我們使用路由屬性scrollBehavior解決這個問題。它與屬性routes是同一級別的屬性。
//router.js scrollBehavior(to, from, savedPosition) { if (savedPosition) { return savedPosition } else { const position = {} if(to.hash) { position.selector = to.hash if(to.hash === "#anchor") { position.offset = { y: 100 } } } if (to.matched.some(m => m.meta.scrollToTop)) { position.x = 0 position.y = 0 } return position; } }為了后面定位到錨點,我們改造FriendMessage,為鏈接到下一個消息列表的連接添加hash#anchor
用戶組消息 修改GroupMessage
- 用戶組消息{{item}}
- 用戶組消息30
- 用戶組消息{{item+30}}
其他消息 - 用戶組消息{{item+50}}
scrollBehavior接收3個參數(shù)to、from和savedPosition。以上函數(shù)中savedPosition當(dāng)且僅當(dāng) popstate 導(dǎo)航 (通過瀏覽器的 前進/后退 按鈕觸發(fā)) 時可用,這里與默認的效果沒區(qū)別。我們獲取to路由的元數(shù)據(jù)meta.scrollToTop(保存自定義的數(shù)據(jù)),當(dāng)為true時我們切換到to對應(yīng)的頁面時,我們定位到{x:0,y:0},否則保持默認行為。如果to存在hash,設(shè)置{selector:to.hash}定位到錨點,可以具體定位錨點定位的偏移量{selector:to.hash,offset:{y:100}}。
History模式code 0.8
在以上所有的請求路徑都帶#,這不是我們所期望的,但是可用于所有的瀏覽器,這種模式為默認的hash模式,如:
http://localhost:8080/#/settings/useremail現(xiàn)在使用history模式,設(shè)置屬性mode
mode:"history", routes: [/*...*/], scrollBehavior(to, from, savedPosition) {/*...*/}現(xiàn)在路徑就正常了,但它只能用于支持H5 History API的瀏覽器。
http://localhost:8080/settings/useremailHistory API需要服務(wù)器的支持,否則當(dāng)重載頁面時,會發(fā)生404頁面找不到,就像下面這樣。
這里使用webpack-dev-server,設(shè)置webpack的devServer.historyApiFallback為true,使其支持History API。如
devServer: { historyApiFallback:true, noInfo: true },其他服務(wù)器的配置見官方文檔后端配置例子
然后又發(fā)現(xiàn)一個bug,像下面這樣,顯示http://localhost:8080/settings/app.js找不到
其實這是個webpack的問題,插入js資源時,像下面這樣
它是相對于當(dāng)前請求的路徑,為了解決這個問題,我們要在webpack中設(shè)置output中的publicPath屬性為/
output: { path: path.resolve(__dirname, "./dist"), publicPath: "/", filename: "[name].js", },它在所有資源前加上虛擬路徑/,app.js就變?yōu)榻^對路徑localhost:8080/app.js,這下就沒什么問題了。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/94100.html
摘要:路由過程的個步驟每次點擊鏈接或瀏覽器改變時,路由器都會確保應(yīng)用程序做出相應(yīng)的反應(yīng)。一旦所有的都已完成,其返回值是合并的路徑的然后路由器繼續(xù)步驟。你可以使用助記記住路由器經(jīng)過的步驟的順序。 路由過程的7個步驟 每次點擊鏈接或瀏覽器URL改變時,Angular路由器都會確保應(yīng)用程序做出相應(yīng)的反應(yīng)。 為了做到這一點,Angular路由器執(zhí)行以下7個步驟的順序: 解析(Parse):它解析...
摘要:一個路由復(fù)用策略用例下面貼一個路由復(fù)用策略用例,應(yīng)該是滿足大部分人的業(yè)務(wù)要求,注意事項只能是末級路由的緩存,且路由切換的時候路由節(jié)點上的不能超過兩個。 關(guān)于路由復(fù)用策略網(wǎng)上的文章很多,大多是講如何實現(xiàn)tab標簽切換歷史數(shù)據(jù),至于如何復(fù)用的原理講的都比較朦朧,代碼樣例也很難適用各種各樣的路由配置,比如懶加載模式下多級嵌套路由出口網(wǎng)上的大部分代碼都會報錯。我希望能通過這篇文章把如何復(fù)用路由...
摘要:默認路由表不允許刪除編輯,默認路由表中的規(guī)則均為系統(tǒng)路由。路由表生效粒度為子網(wǎng)。每個子網(wǎng)必須要綁定且只能綁定一張路由表,一張路由表可被多個子網(wǎng)綁定。每張路由表最多支持條自定義路由規(guī)則。路由表簡介名詞解釋默認路由表:創(chuàng)建VPC時系統(tǒng)默認為VPC創(chuàng)建的路由表。新創(chuàng)建的子網(wǎng)將默認綁定默認路由表。默認路由表不允許刪除、編輯,默認路由表中的規(guī)則均為系統(tǒng)路由。自定義路由表:用戶自主創(chuàng)建的路由表,并可自定...
閱讀 3569·2021-11-18 13:20
閱讀 2727·2021-10-15 09:40
閱讀 1740·2021-10-11 10:58
閱讀 2107·2021-09-27 13:36
閱讀 2586·2021-09-07 10:06
閱讀 1848·2021-08-11 11:21
閱讀 1425·2019-08-29 17:04
閱讀 2080·2019-08-29 14:06