Vue Router 是 Vue.js 的官方路由管理器,在官方文檔中描述的功能包括:html
這裏,仍是先附上官方文檔的連接:https://router.vuejs.org/zh/vue
(1)經過 CDN 引用java
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
(2)經過 NPM 安裝與使用vue-router
> npm install vue-router
在項目中須要經過 Vue.use()
明確安裝路由功能shell
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter)
下面,咱們用一個簡單的例子來體會一下 Vue Router 的基本使用方法npm
首先建立一個命名爲 index.html
的文件,而後在文件中輸入以下代碼(具體請看代碼註釋):編程
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> </head> <body> <div id="app"> <h1>Hello</h1> <p> <!-- 默認渲染成 <a> 標籤,經過 to 屬性指定路徑 --> <router-link to="/home">Home</router-link> | <router-link to="/about">About</router-link> </p> <!-- 路由匹配到的組件渲染到這裏 --> <router-view></router-view> </div> <script> // 一、定義組件 const Home = { template: ` <div> <h3>Home Page Here</h3> <p>This is home page</p> </div> ` } const About = { template: ` <div> <h3>About Page Here</h3> <p>This is about page</p> </div> ` } // 二、定義路由 const routes = [ { path: '/home', // 匹配的路徑 component: Home // 顯示的組件 }, { path: '/about', component: About } ] // 三、建立 router 實例,傳入 routes 配置 const router = new VueRouter({ routes // 縮寫,至關於 routes : routes }) // 四、建立並掛載根實例 const app = new Vue({ router // 注入路由 }).$mount('#app') </script> </body> </html>
當咱們打開頁面時,URL 爲 index.html#/
app
若是咱們點擊 Home
,URL 跳轉爲 index.html#/home
(此時,匹配路由 /home
,顯示組件 Home)模塊化
若是點擊 About
,URL 跳轉爲 index.html#/about
(此時,匹配路由 /about
,顯示組件 About)
下面考慮這樣一個需求,咱們要爲路由 /user/Alice
和 /user/Bob
指定使用同一個組件 User
再泛化一點來講就是爲每個不一樣的用戶(路由爲 /user/xxx
)都指定使用同一個組件
這時候,動態路由就能夠派上用場啦
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> </head> <body> <div id="app"> <h1>Hello</h1> <router-view></router-view> </div> <script> const User = { // 在模板中咱們能夠用 $route 對象中的 params 屬性得到 URL 參數 template: '<p>The user name is {{ $route.params.name }}</p>' } const routes = [ { path: '/user/:name', // 以冒號開頭表示參數,能夠同時使用多個參數 component: User } ] const router = new VueRouter({ routes }) const app = new Vue({ router }).$mount('#app') </script> </body> </html>
這時候,咱們手動輸入 URL index.html#/user/Alice
,頁面會顯示 The user name is Alice
若是再輸入 index.html#/user/Bob
,頁面顯示會變成 The user name is Bob
可是須要注意,從 /user/Alice
導航到 /user/Bob
,原來的組件將會被複用,而不是從新建立
這意味着什麼?這意味着組件的生命週期鉤子不會再被調用
若是但願路由參數變化時組件可以做出響應,有兩個辦法:
watch
屬性監測 $route
對象const User = { template: ` <div> <p>The user name is {{ $route.params.name }}</p> </div> `, watch: { '$route': function (to, from) { console.log('changed') } } }
beforeRouteUpdate
導航護衛const User = { template: ` <div> <p>The user name is {{ $route.params.name }}</p> </div> `, beforeRouteUpdate (to, from, next) { console.log('changed') } }
在上面的例子中,咱們使用 path
標識一個路由,事實上,咱們還可使用 name
爲路由設置名稱
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> </head> <body> <div id="app"> <h1>Hello</h1> <!-- 在連接到一個命名路由時,須要給 <router-link> 元素的 to 屬性動態綁定一個對象 --> <router-link :to="{ name: 'user', params: { name: 'Alice'} }">To Alice User Page</router-link> </div> <script> const User = { template: '<p>The user name is {{ $route.params.name }}</p>' } const routes = [ { name: 'user', // 爲路由設置名稱 path: '/user/:name', component: User } ] const router = new VueRouter({ routes }) const app = new Vue({ router }).$mount('#app') </script> </body> </html>
與上面相似,咱們可使用 name
爲 <router-view>
設置名稱,這容許咱們在一個路由中使用多個同級的視圖
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> </head> <body> <div id="app"> <h1>Hello</h1> <router-link to="/home">To Home Page</router-link> <router-view name="header"></router-view> <!-- 爲視圖設置名稱 --> <router-view></router-view> <!-- 沒有命名,默認爲 default --> <router-view name="footer"></router-view> </div> <script> const Header = { template: '<h3>This is header</h3>' } const Container = { template: '<span>This is container</span>' } const Footer = { template: '<p>This is footer</p>' } const routes = [ { path: '/home', // 使用 components 選項,不是 component components: { // 對象,鍵爲視圖名稱,值爲組件名稱 default: Container, header: Header, footer: Footer } } ] const router = new VueRouter({ routes }) const app = new Vue({ router }).$mount('#app') </script> </body> </html>
在實際應用中,除了會有使用多個同級視圖的狀況,還有使用嵌套視圖的狀況,這時候咱們有嵌套路由與之匹配
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> </head> <body> <div id="app"> <h1>Hello</h1> <router-link to="/home">To Home Page</router-link> <router-link to="/home/intro">To Intro Page</router-link> <router-link to="/home/info">To Info Page</router-link> <router-view></router-view> </div> <script> const Home = { // 在組件中也能夠包含 <router-view> template: ` <div> <p>This is home page</p> <router-view></router-view> </div> ` } const Info = { template: '<p>This is info page</p>' } const Intro = { template: '<p>This is intro page</p>' } const routes = [ { path: '/home', component: Home, // 使用 children 選項,至關於在子組件中配置 routes children: [ { path: 'intro', // 至關於 /home/intro component: Intro // 渲染在 Home 的 <router-view> 中 }, { path: 'info', // 至關於 /home/info component: Info // 渲染在 Home 的 <router-view> 中 } ] } ] const router = new VueRouter({ routes }) const app = new Vue({ router }).$mount('#app') </script> </body> </html>
還記得在動態路由那一小節的例子嗎?咱們使用 $route.params
獲取 URL 參數
const User = { template: '<p>The user name is {{ $route.params.name }}</p>' } const routes = [ { path: '/user/:name', component: User } ]
這樣的寫法,使得組件與對應的路由高度耦合,因此咱們可使用 props
進行解耦
const User = { props: ['name'], // 使用 props 屬性 template: '<p>The user name is {{ name }}</p>' } const routes = [ { path: '/user/:name', component: User, props: true // 使用 props 屬性,除了使用布爾值,還可使用對象和函數 } ]
在上面的例子中咱們屢次使用 <router-link>
進行導航,實際上咱們還可使用 router.push()
該方法有三個參數,分別是 location、onComplete 和 onAbort,它們的含義以下:
router.replace()
與 router.push()
十分相似
不一樣之處在於 push
會向 history 棧中添加新的記錄,而 replace()
將會直接替換當前的 history 記錄
【 閱讀更多 Vue 系列文章,請看 Vue學習筆記 】