1. Vue Router簡介與安裝
1.1 Vue Router簡介
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度整合,構建單頁面應用。
Vue Router支援3種路由模式:
◊ hash:使用URL hash值作為路由
◊ history:依賴HTML5 History API和伺服器配置
◊ abstract:支援所有JavaScript執行環境,如node伺服器端。如果發現沒有瀏覽器的API,路由就會強制進入該模式。
vue-router提供兩個指令標籤元件來處理這個導航與自動渲染邏輯:
◊ <router-view>:渲染路徑匹配到的元件檢視
◊ <router-link>:支援使用者在具有路由功能的應用中導航
1.2 Vue Router安裝
Vue Router官方網址:https://github.com/vuejs/vue-router
Vue Router文件教程:https://router.vuejs.org/zh/
npm安裝VueRouter:
npm install vue-router
2. 起步示例
2.1 單個html頁面中使用
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>libing.vue</title> <script src="node_modules/vue/dist/vue.min.js"></script> <script src="node_modules/vue-router/dist/vue-router.min.js"></script> </head> <body> <div id="app"> <ul> <li> <router-link to="/home">Home</router-link> </li> <li> <router-link to="/about">About</router-link> </li> </ul> <router-view></router-view> </div> <template id="home"> <div>Home</div> </template> <template id="about"> <div>About</div> </template> <script> var home = Vue.extend({ template: "#home" }); var about = Vue.extend({ template: "#about" }); const routes = [{ path: '/home', component: home },{ path: '/about', component: about } ]; const router = new VueRouter({ routes: routes }); const app = new Vue({ router }).$mount('#app'); </script> </body> </html>
2.2 vue-cli中模組化使用
(1)建立基於vue-cli專案
$ vue init webpack libing.vue
專案結構:
(2)/src/views中新建Home.vue及About.vue
<template> <div>{{ title }}</div> </template> <script> export default { data: function() { return { title: "主頁" }; } }; </script>
<template> <div>{{ title }}</div> </template> <script> export default { data: function() { return { title: "關於" }; } }; </script>
(3)/src/route/index.js
import Vue from 'vue' import Router from 'vue-router' import Home from '@/views/Home' import About from '@/views/About' Vue.use(Router) export default new Router({ routes: [{ path: '/', name: 'home', component: Home }, { path: '/home', name: 'home', component: Home }, { path: '/about', name: 'about', component: About } ] })
(4)/src/App.vue
<template> <div id="app"> <ul> <li> <router-link to="/home">Home</router-link> </li> <li> <router-link to="/about">About</router-link> </li> </ul> <router-view/> </div> </template> <script> export default { name: "App" }; </script>
其餘未做改動部分:
Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { App }, template: '<App/>' })
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>libing.vue</title> </head> <body> <div id="app"></div> <!-- built files will be auto injected --> </body> </html>
在router-link通過名稱引用路由:向to屬性傳入一個物件顯式的宣告路由的名稱。
<router-link :to="{ name: 'home' }">Home</router-link>
注:在/src/route/index.js中配置路由路徑時,建立Router 物件new Router({}),如果不配置 mode,就會使用預設的 hash 模式,該模式下會將路徑格式化為 #! 開頭。
設定 mode: "history"
將使用 HTML5 history 模式,該模式下沒有 # 字首,而且可以使用 pushState 和 replaceState 來管理記錄。
import Vue from 'vue' import Router from 'vue-router' import Home from '@/views/Home' import About from '@/views/About' Vue.use(Router) export default new Router({ mode: 'history', routes: [{ path: '/', name: 'home', component: Home }, { path: '/home', name: 'home', component: Home }, { path: '/about', name: 'about', component: About } ] })
3. 動態路由匹配
在 vue-router 的路由路徑中使用“動態路徑引數”(dynamic segment) ,動態部分 以 : 開頭。
/src/router/index.js
import Vue from 'vue' import Router from 'vue-router' import Home from '@/views/Home' import About from '@/views/About' import User from '@/views/User' Vue.use(Router) export default new Router({ mode: 'history', routes: [{ path: '/', component: Home }, { path: '/home', component: Home }, { path: '/about', component: About }, { // 動態路徑引數 以冒號開頭 path: '/user/:id', component: User } ] })
User.vue:
<template> <div>User ID:{{ $route.params.id }}</div> </template> <script> export default { } </script>
App.vue:
<template> <div id="app"> <ul> <li> <router-link to="/home">Home</router-link> </li> <li> <router-link to="/about">About</router-link> </li> <li> <router-link to="/user/1">User ID:1</router-link> </li> <li> <router-link to="/user/2">User ID:2</router-link> </li> </ul> <router-view/> </div> </template> <script> export default { name: "App" }; </script>
在User.vue中直接通過 {{ $route.params.id }} 獲取路由中路徑引數值。
當整個vue-router 注入到根例項後,在元件的內部,可以通過this.$route 來獲取到 router 例項。
$route中params 屬性來獲得動態部分,params 屬性是一個物件。
屬性名是路徑中定義的動態部分 id, 屬性值是router-link中to 屬性中的動態部分。
在<router-link>中加入一個params的屬性來指定具體的引數值。
<router-link :to="{ name: 'user', params:{ id: 1 }}">UserID:1</router-link>
4. 巢狀路由
實際應用介面,通常由多層巢狀的元件組合而成。
vue-router配置巢狀路示例:
App.vue
<template> <div id="app"> <ul> <li> <router-link to="/home">Home</router-link> </li> <li> <router-link :to="{ name: 'about' }">About</router-link> </li> <li> <router-link :to="{ name: 'user', params:{ id: 1 }}">UserID:1</router-link> </li> <li> <router-link to="/user/2">UserID:2</router-link> </li> </ul> <router-view/> </div> </template> <script> export default { name: "App" }; </script>
這裡的<router-view>是最頂層的出口,渲染最高階路由匹配到的元件。
一個被渲染元件同樣可以包含自己的巢狀 <router-view>。
User.vue
<template> <div> <h2>User ID:{{ $route.params.id }}</h2> <router-view></router-view> </div> </template> <script> export default {}; </script>
要在巢狀的出口中渲染元件,需要在 VueRouter 的引數中使用 children 配置:
index.js
import Vue from 'vue' import Router from 'vue-router' import Home from '@/views/Home' import About from '@/views/About' import User from '@/views/User' import UserProfile from '@/views/UserProfile' Vue.use(Router) export default new Router({ mode: 'history', routes: [{ path: '/', name: 'home', component: Home }, { path: '/home', name: 'home', component: Home }, { path: '/about', name: 'about', component: About }, { // 動態路徑引數 以冒號開頭 path: '/user/:id', name: 'user', component: User, children: [{ // 當 /user/:id/profile 匹配成功, // UserProfile 會被渲染在 User 的 <router-view> 中 path: 'profile', name: 'profile', component: UserProfile }] } ] })
UserProfile.vue
<template> <div>User Profile</div> </template> <script> export default {}; </script>
訪問巢狀路由方式:http://localhost:8080/user/1/profile
在巢狀路由中訪問父級路由引數:
<template> <div>User Profile:{{ $route.params.id }}</div> </template> <script> export default {}; </script>
當訪問 /user/1 時,提供一個 空的子路由。
{ // 動態路徑引數 以冒號開頭 path: '/user/:id', name: 'user', component: User, children: [{ // 當 /user/:id 匹配成功, // UserProfile 會被渲染在 User 的 <router-view> 中 path: '', component: UserProfile }, { // 當 /user/:id/profile 匹配成功, // UserProfile 會被渲染在 User 的 <router-view> 中 path: 'profile', name: 'profile', component: UserProfile }] }
5. 命名檢視
若要同級展示多個檢視(非巢狀),使用命名檢視。
如果router-view沒有設定名字,則預設為 default。
<router-view name="main"></router-view>
一個檢視使用一個元件渲染,因此對於同個路由,多個檢視就需要多個元件。使用 components 配置。
<router-view name="header"></router-view> <router-view name="slidebar"></router-view> <router-view name="main"></router-view> <router-view name="footer"></router-view>
Route配置:
export default new Router({ routes: [{ path: '/', name: 'home', components: { default: Home, header: Header, slidebar: SlideBar, footer: Footer } } ] })
命名巢狀檢視:
<template> <div> <h2>User ID:{{ $route.params.id }}</h2> <router-view></router-view> <router-view name="defined"></router-view> </div> </template> <script> export default {}; </script>
export default new Router({ routes: [{ // 動態路徑引數 以冒號開頭 path: '/user/:id', name: 'user', component: User, children: [{ // 當 /user/:id 匹配成功, // UserProfile 會被渲染在 User 的 <router-view> 中 path: '', component: UserProfile }, { // 當 /user/:id/profile 匹配成功, // UserProfile 會被渲染在 User 的 <router-view> 中 path: 'profile', name: 'profile', components: { default: UserProfile, defined: UserDefinedProfile } }] } ] })