本文是基於官網學習,官網具體學習目錄:vue-routerhtml
基於vue-cli腳手架安裝仍是蠻簡單的:在文件當前目錄下運行:vue
npm install vue-router
若是在一個模塊化工程中使用它,必需要經過 Vue.use()
明確地安裝路由功能:vue-router
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter)
腳手架安裝教程: 腳手架安裝教程 vue-cli
其餘類型安裝詳見官網:安裝npm
官網介紹的已經很全面。編程
<script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <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> // 0. 若是使用模塊化機制編程,導入Vue和VueRouter,要調用 Vue.use(VueRouter) // 1. 定義(路由)組件。 // 能夠從其餘文件 import 進來 const Foo = { template: '<div>foo</div>' } const Bar = { template: '<div>bar</div>' } // 2. 定義路由 // 每一個路由應該映射一個組件。 其中"component" 能夠是 // 經過 Vue.extend() 建立的組件構造器, // 或者,只是一個組件配置對象。 // 咱們晚點再討論嵌套路由。 const routes = [{ path: '/foo', component: Foo }, { path: '/bar', component: Bar }] // 3. 建立 router 實例,而後傳 `routes` 配置 // 你還能夠傳別的配置參數, 不過先這麼簡單着吧。 const router = new VueRouter({ routes // (縮寫)至關於 routes: routes }) // 4. 建立和掛載根實例。 // 記得要經過 router 配置參數注入路由, // 從而讓整個應用都有路由功能 const app = new Vue({ router }).$mount('#app') // 如今,應用已經啓動了! </script> <!-- 要注意,當 <router-link> 對應的路由匹配成功,將自動設置 class 屬性值 .router-link-active --> <style> .router-link-active { color: red; } </style>
效果:segmentfault
這個案例,就是不一樣路徑顯示不一樣組件。瀏覽器
咱們常常須要把某種模式匹配到的全部路由,全都映射到同個組件。好比/user/name、/user/age、/user/haha都要映射到user組件,怎麼作呢?app
<script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <div id="app"> <p> <router-link to="/user/foo">/user/foo</router-link> <router-link to="/user/bar">/user/bar</router-link> </p> <router-view></router-view> </div> <script> //一個『路徑參數』使用冒號 : 標記。當匹配到一個路由時, //參數值會被設置到 this.$route.params,能夠在每一個組件內使用。因而,咱們能夠更新 User 的模板 //輸出當前用戶的 ID const User = { template: `<div>User {{ $route.params.id }}</div>` } // 動態路徑參數 以冒號開頭 //如今呢,像 /user/foo 和 /user/bar 都將映射到相同的路由。 const router = new VueRouter({ routes: [{ path: '/user/:id', component: User }] }) const app = new Vue({ router }).$mount('#app') </script> <style> .router-link-active { color: red; } </style>
效果: 模塊化
你能夠在一個路由中設置多段『路徑參數』,對應的值都會設置到 $route.params
中。例如:
模式 | 匹配路徑 | $route.params | |
---|---|---|---|
/user/:username | /user/evan | { username: 'evan' } |
|
/user/:username/post/:post_id | /user/evan/post/123 | { username: 'evan', post_id: 123 } |
嵌套路由是個常見的需求,假設用戶可以經過路徑/home/news
和/home/message
訪問一些內容,一個路徑映射一個組件,訪問這兩個路徑也會分別渲染兩個組件。
實現嵌套路由有兩個要點:
<router-view>
標籤VueRouter
的參數中使用 children
配置<div id="app"> <router-view></router-view> </div>
這裏的 <router-view>
是最頂層的出口,渲染最高級路由匹配到的組件。一樣地,一個被渲染組件一樣能夠包含本身的嵌套 <router-view>
。例如,在 User
組件的模板添加一個 <router-view>
const User = { template: ` <div class="user"> <h2>User {{ $route.params.id }}</h2> <router-view></router-view> </div> ` }
要在嵌套的出口中渲染組件,須要在 VueRouter
的參數中使用 children
配置
const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, children: [ { // 當 /user/:id/profile 匹配成功, // UserProfile 會被渲染在 User 的 <router-view> 中 path: 'profile', component: UserProfile }, { // 當 /user/:id/posts 匹配成功 // UserPosts 會被渲染在 User 的 <router-view> 中 path: 'posts', component: UserPosts } ] } ] })
要注意,以 /
開頭的嵌套路徑會被看成根路徑。 這讓你充分的使用嵌套組件而無須設置嵌套的路徑。
此時,基於上面的配置,當你訪問 /user/foo
時,User
的出口是不會渲染任何東西,這是由於沒有匹配到合適的子路由。若是你想要渲染點什麼,能夠提供一個 空的 子路由:
const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, children: [ // 當 /user/:id 匹配成功, // UserHome 會被渲染在 User 的 <router-view> 中 { path: '', component: UserHome }, // ...其餘子路由 ] } ] })
綜合小案例:
<script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <div id="app"> <p> <router-link to="/user/foo">/user/foo</router-link> <router-link to="/user/foo/profile">/user/foo/profile</router-link> <router-link to="/user/foo/posts">/user/foo/posts</router-link> </p> <router-view></router-view> </div> <script> const User = { template: ` <div class="user"> <h2>User {{ $route.params.id }}</h2> <router-view></router-view> </div> ` } const UserHome = { template: '<div>Home</div>' } const UserProfile = { template: '<div>Profile</div>' } const UserPosts = { template: '<div>Posts</div>' } const router = new VueRouter({ routes: [{ path: '/user/:id', component: User, children: [{ // /user/:id/匹配到UserHome組件,若是你是/user/:id/home是匹配不到任何組件的,由於children裏沒有home路徑 path: '', component: UserHome }, { // /user/:id/profile匹配到UserProfile組件 path: 'profile', component: UserProfile }, { // /user/:id/posts匹配到UserPosts組件 path: 'posts', component: UserPosts } ] }] }) const app = new Vue({ router }).$mount('#app') </Script>
效果:
router.push
上面幾種路由都是直接在頁面點擊進行跳轉,但在咱們實際開發過程當中,有不少按鈕在執行跳轉以前,還會執行一系列方法,這時可使用 this.$router.push(location) 來修改 url,完成跳轉
想要導航到不一樣的 URL,則使用 router.push
方法。這個方法會向 history 棧添加一個新的記錄,因此,當用戶點擊瀏覽器後退按鈕時,則回到以前的 URL。
當你點擊 <router-link>
時,這個方法會在內部調用,因此說,點擊 <router-link :to="...">
等同於調用 router.push(...)
。
聲明式 | 編程式 |
---|---|
<router-link :to="..."> |
router.push(...) |
該方法的參數能夠是一個字符串路徑,或者一個描述地址的對象。例如:
// 字符串 router.push('home') // 對象 router.push({ path: 'home' }) // 命名的路由 router.push({ name: 'user', params: { userId: 123 }}) // 帶查詢參數,變成 /register?plan=private router.push({ path: 'register', query: { plan: 'private' }})
注意:若是提供了 path
,params
會被忽略,上述例子中的 query
並不屬於這種狀況。取而代之的是下面例子的作法,你須要提供路由的 name
或手寫完整的帶有參數的 path
const userId = 123 router.push({ name: 'user', params: { userId }}) // -> /user/123 router.push({ path: `/user/${userId}` }) // -> /user/123 // 這裏的 params 不生效 router.push({ path: '/user', params: { userId }}) // -> /user
一樣的規則也適用於 router-link
組件的 to
屬性。
router.replace
跟 router.push
很像,惟一的不一樣就是,它不會向 history 添加新記錄,而是跟它的方法名同樣 —— 替換掉當前的 history 記錄。(下面會具體說明)
聲明式 | 編程式 |
---|---|
<router-link :to="..." replace> |
router.replace(...) |
router.go(n)
這個方法的參數是一個整數,意思是在 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)
1.this.$router.push():
跳轉到不一樣的url,但這個方法迴向history棧添加一個記錄,點擊後退會返回到上一個頁面。
2.this.$router.replace()
一樣是跳轉到指定的url,可是這個方法不會向history裏面添加新的記錄,點擊返回,會跳轉到上上一個頁面。上一個記錄是不存在的。
3.this.$router.go(n)
相對於當前頁面向前或向後跳轉多少個頁面,相似 window.history.go(n)
。n可爲正數可爲負數。正數返回上一個頁面
四、在什麼狀況用push,或者在上面狀況用replace,我的理解:
通常狀況下,要作前進後退的瀏覽記錄管理的,基本上都是用router.push()
,可是也是有一些特殊狀況須要用到router.replace()
。好比,有一個受權頁,用戶在按流程操做時,某一步須要受權,是直接跳到受權頁,受權頁提交受權請求,直到成功受權後,跳到流程中的下一步操做的地址。此處,受權請求的那頁面應該用replace
去替換掉自身的訪問記錄,防止用戶跳到下一步流程後按後退鍵回退到受權頁,而致使重複受權,簡單來說就是你跳過來了,就不讓你後退又到上一個頁面。
舉例:
<script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <div id="app"> <button type="button" @click="fooClick">/user/foo</button> <button type="button" @click="profileClick">/user/foo/profile</button> <button type="button" @click="postsClick">/user/foo/posts</button> <router-view></router-view> </div> <script> //定義了三個組件 const UserHome = { template: '<div>Home</div>' } const UserProfile = { template: '<div>Profile</div>'} const UserPosts = { template: '<div>Posts</div>' } //匹配了三個路由 const router = new VueRouter({ routes: [{ path: '/user/foo', component: UserHome, }, { path: '/user/foo/profile', component: UserProfile, }, { path: '/user/foo/posts', component: UserPosts, }] }) const app = new Vue({ el: '#app', router, data: { foo: '/user/foo', profile: '/user/foo/profile', posts: '/user/foo/posts' }, methods: { fooClick: function(event) { this.$router.push({ path: this.foo }); }, profileClick: function(event) { this.$router.push({ path: this.profile }); }, postsClick: function(event) { this.$router.push({ path: this.posts }); } } }) </Script>
頁面:
測試結果:當使用 this.$router.push,時,前進一步後退一步都會退到上一次進入的頁面,而使用 this.$router.replace並不不會調到上一個頁面。
想太多,作太少,中間的落差就是煩惱。想沒有煩惱,要麼別想,要麼多作。中尉【19】