在web開發中,"router"是指根據url分配到對應的處理程序html
//vue <script src="https://unpkg.com/vue/dist/vue.js"></script> //vue-router <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
npm install vue-router
在使用Vue.js的時候,咱們經過組合組件來組成應用程序,如今咱們要把vue-router添加進來,只須要將組件(components)映射到路由(routes),而後告訴 vue-router 在哪裏渲染它們。vue
<div id="app"> <h1>Hello App!</h1> <p> <!-- 使用 router-link 組件來導航. --> <!-- 經過傳入 `to` 屬性指定連接. --> <!-- <router-link> 默認會被渲染成一個 `<a>` 標籤 --> <router-link to="/foo">Go to Foo</router-link> <router-link to="/bar">Go to Bar</router-link> </p> <!-- 路由出口 --> <!-- 路由匹配到的組件將渲染在這裏 --> <router-view></router-view> </div> <script> // 1. 定義(路由)組件。 const Foo = { template: '<div>foo</div>' } const Bar = { template: '<div>bar</div>' } // 2. 定義路由 const routes = [ { path: '/foo', component: Foo }, { path: '/bar', component: Bar } ] // 3. 建立 router 實例,而後傳 `routes` 配置 const router = new VueRouter({ routes // (縮寫)至關於 routes: routes }) // 4. 建立和掛載根實例。 const app = new Vue({ el:'#app', router }) </script>
注意,若是使用模塊化編程。就須要導入vue和VueRouter,在js中調用 Vue.use(VueRouter)web
例如,咱們有一個 User 組件,對於全部 ID 各不相同的用戶,都要使用這個組件來渲染。那麼,咱們能夠在 vue-router 的路由路徑中使用『動態路徑參數』(dynamic segment)來達到這個效果:vue-router
HTMLshell
div id="app"> <h1>Hello App!</h1> <p> <router-link to="/foo">Go to Foo</router-link><br/> <router-link to="/bar">Go to Bar</router-link><br/> <router-link to="/user">user</router-link> </p> <router-view></router-view> </div>
JAVASCRIPTnpm
onst Foo = { template: '<div>foo</div>' } const Bar = { template: '<div>bar</div>' } const User = {template:` <div> <h2>user</h2> {{$route.params.name}} </div>` } const routes = [ { path: '/foo', component: Foo }, { path: '/bar', component: Bar }, { path:'/user', component:User, children:[ { path:':name'//動態路徑參數以冒號開頭 } ] } ] const router = new VueRouter({ routes }) const app = new Vue({ el:'#app', router })
藉助 vue-router,使用嵌套路由配置,就能夠很簡單地表達組件中的層級關係編程
實際上,在上面的動態路由的例子中就已經使用了嵌套了,定義路由時添加一個 children 屬性便可:數組
const routes=[ { path:'/user', component:User, children:[ { path:':name', component:{ template:'<div>pureview</div>' } } ] } ]
< router-view >標籤在模板中會被渲染爲一個< a >標籤來進行連接,其實,也可使用 "router.push()" 來實現導航瀏覽器
<div id="app"> <input value="按鈕" type="button" v-on:click="btn"> </div> <script> new Vue({ el:'#app', methods:{ btn:function(){ router.push('/user') } } }) </script>
該方法的參數能夠是一個字符串路徑,或者一個描述地址的對象。例如:app
// 字符串 router.push('home') // 對象 router.push({ path: 'home' }) // 命名的路由 router.push({ name: 'user', params: { userId: 123 }}) // 帶查詢參數,變成 /register?plan=private router.push({ path: 'register', query: { plan: 'private' }})
跟 router.push 很像,惟一的不一樣就是,它不會向 history 添加新記錄,而是跟它的方法名同樣 —— 替換掉當前的 history 記錄。
這個方法的參數是一個整數,意思是在 history 記錄中向前或者後退多少步,相似 window.history.go(n)。
// 在瀏覽器記錄中前進一步,等同於 history.forward() router.go(1) // 後退一步記錄,等同於 history.back() router.go(-1) // 前進 3 步記錄 router.go(3) // 若是 history 記錄不夠用,那就默默地失敗唄 router.go(-100) router.go(100)
路由組件是能夠進行命名的,在執行連接或者跳轉頁面時就會比較方便。命名的方式也很簡單,給routes一個name屬性就OK了
var router=new VueRouter({ routes:[ { path:'/home', name:'homePage', component:Home } ] })
要連接到一個命名路由,能夠給 router-link 的 to 屬性傳一個對象:
<router-link to="{name:'homePage'}">Home</router-link>
有時候想同時(同級)展現多個視圖,而不是嵌套展現,例如建立一個佈局,有 sidebar(側導航) 和 main(主內容) 兩個視圖,這個時候命名視圖就派上用場了。你能夠在界面中擁有多個單獨命名的視圖,而不是隻有一個單獨的出口。若是 router-view 沒有設置名字,那麼默認爲 default。
HTML
<div id="app"> <div> <h2>視圖一</h2> <router-view name="one"></router-view> </div> <div> <h2>視圖二</h2> <router-view name="two"></router-view> </div> </div>
JAVASCRIPT
var Foo={ template:'<div>內容一</div>' } var Bar={ template:'<div>內容二</div>' } var routes=[ { path:'/', components:{ one:Foo, two:Bar } } ] var router=new VueRouter({ routes })
重定向的意思就是當你訪問 a 的時候,url 會被替換爲 b ,因而匹配路由 b
重定向也是經過 routes 配置來完成,下面例子是從 /a 重定向到 /b:
var router=new VueRouter({ routes:[ { path:'/a', redirect:'/b' } ] })
意思就是當咱們訪問 b 的時候,路由匹配爲 a ,可是url地址不變
var router=new VueRouter({ routes:[ { path:'/a', alias:'/b' } ] })
vue-router 提供的導航鉤子主要用來攔截導航,讓它完成跳轉或取消。有多種方式能夠在路由導航發生時執行鉤子:全局的, 單個路由獨享的, 或者組件級的。
你可使用 router.beforeEach 註冊一個全局的 before 鉤子:
router .beforeEach((to,from,next)=>{ //... })
鉤子函數的三個參數:
to: Route: 即將要進入的目標 路由對象
from: Route: 當前導航正要離開的路由
next: Function: 必定要調用該方法來 resolve 這個鉤子。執行效果依賴 next 方法的調用參數。
next(): 進行管道中的下一個鉤子。若是所有鉤子執行完了,則導航的狀態就是 confirmed (確認的)。
next(false): 中斷當前的導航。若是瀏覽器的 URL 改變了(多是用戶手動或者瀏覽器後退按鈕),那麼 URL 地址會重置到 from 路由對應的地址。
next('/') 或者 next({ path: ' / ' }): 跳轉到一個不一樣的地址。當前的導航被中斷,而後進行一個新的導航。
作一個小例子:
作了一個簡單的頁面,設定了一個登錄狀態,若是 isLogin 爲false,那麼點擊帳戶中心,則跳轉到登錄頁進行登錄
若是 isLogin 爲true,則顯示帳戶中心的內容:
鉤子函數代碼
router.beforeEach((to, from, next) => { var isLogin = true ; if(to.path == "/user"&&!isLogin){ next("/login") }else{ next(); } })
貼上完整代碼你們能夠直接複製試一試
<div id="app"> <p> <router-link to="/foo">首頁</router-link> <router-link to="/bar">關於咱們</router-link> <router-link to="/user">帳戶中心</router-link> <router-link to="/login">登陸</router-link> </p> <router-view></router-view> </div> <script> var Foo = { template:"<div>我是首頁</div>" } var Bar = { template:"<div>我是關於咱們</div>" } var User = { template:"<div>我是帳戶中心</div>" } var Login = { template:"<div>我是登陸</div>" } var routes = [ {path:"/foo" , component:Foo}, {path:"/bar" , component:Bar}, {path:"/user" , component:User}, {path:"/login" , component:Login} ] var router = new VueRouter({ routes }) router.beforeEach((to, from, next) => { var isLogin = true ; if(to.path == "/user"&&!isLogin){ next("/login") }else{ next(); } }) var app = new Vue({ el:"#app", router }); </script>
定義路由的時候能夠配置 meta 字段:
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, children: [ { path: 'bar', component: Bar, meta: { requiresAuth: true } } ] } ] })
那麼如何訪問這個 meta 字段呢?
首先,咱們稱呼 routes 配置中的每一個路由對象爲 路由記錄。路由記錄能夠是嵌套的,所以,當一個路由匹配成功後,他可能匹配多個路由記錄。
例如,根據上面的路由配置,/foo/bar 這個 URL 將會匹配父路由記錄以及子路由記錄。
一個路由匹配到的全部路由記錄會暴露爲 $route 對象(還有在導航鉤子中的 route 對象)的 $route.matched 數組。所以,咱們須要遍歷 $route.matched 來檢查路由記錄中的 meta 字段。
下面例子展現在全局導航鉤子中檢查 meta 字段:
router.beforeEach((to, from, next) => { if (to.matched.some(record => record.meta.requiresAuth)) { // 此路由須要驗證,檢查是否登陸 // 若是不須要,則重定向到登陸頁面。 if (!auth.loggedIn()) { next({ path: '/login', query: { redirect: to.fullPath } }) } else { next() } } else { next() // 確保必定要調用 next() } })