什麼是路由html
在web開發中,路由是指根據url分配到對應的處理程序,當訪問不一樣的url就會切換到對應的處理程序vue
在vue中一個url對應的就是一個組件,當訪問不一樣的url,對應的組件就會呈現到頁面中node
vue-router:做用是經過管理url,實現url和組件的對應和經過url進行組件之間的切換web
單頁應用(SPA):加載單個html頁面,並在用戶與應用程序交互時動態更新該頁面vue-router
vue-router安裝npm
建立項目過程當中安裝vue-router:在建立項目的時候,能夠安裝vue-router,選擇Y就是安裝,那麼在package.json中是有vue-router這個配置的編程
使用這種安裝方式,在項目src下面會自動生成一個router的目錄,目錄下有個index.js的文件,用做專門配置路由的一個文件json
而且在node_module目錄下也會生成一個vue-router的文件夾瀏覽器
後期安裝vue-router:在doc中進入項目目錄,而後輸入安裝命令:npm install vue-router --save(--save表示將安裝vue-router這個配置到package.josn裏面)緩存
在node-moudle文件夾裏就有了vue-router這些目錄
後期安裝的方式,須要手動在src目錄下建立一個router的目錄,裏面再建立一個叫index.js的文件,用做路由的配置文件
vue-router的簡單配置示例
首先定義兩個組件
<template> <div class="about"> about </div> </template> <script type="text/ecmascript-6"> export default { name: 'about', data () { return {} } } </script> <style scoped></style>
<template> <div>home</div> </template> <script type="text/ecmascript-6"> export default { name: 'home', data () { return {} } } </script> <style scoped></style>
建立一個router目錄,裏面建立一個index.js文件,用於配置路由
import Vue from 'vue' import Router from 'vue-router' // 引入路由模塊 import Home from '@/view/home' import About from '@/view/about' Vue.use(Router) // 將路由模塊做爲插件使用 export default new Router({ routes: [ { path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: About } ] })
而後在main.js中引入,而且注入到vue實例中
import Vue from 'vue' import App from './App' import router from './router' Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, template: '<App/>', components: { App } })
在App.vue中裝載路由
<template> <div id="app"> <router-view></router-view> </div> </template> <script> export default { name: ' app', data () { return {} } } </script>
運行效果
hash和history模式
在路由配置文件裏面,配置mode爲history後,頁面能夠前進和後退,而且路勁上沒有了#
import Vue from 'vue' import Router from 'vue-router' // 引入路由模塊 import Home from '@/view/home' import About from '@/view/about' import Document from '@/view/document' Vue.use(Router) // 將路由模塊做爲插件使用 export default new Router({ mode: 'history', // 設置導航模式,默認是哈希模式,開發中通常使用history模式 routes: [ { path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: About }, { path: '/document', name: 'document', component: Document } ] })
router-link各類配置項
router-link 導航路徑的配置
router-link導航路徑的配置寫法有三種:綁定一個對象的方式;直接寫死的方式;綁定一個變量的方式
<template> <div id="app"> <!--動態綁定對象的寫法--> <router-link v-bind:to="{path: '/home'}">home</router-link> <!--直接將路徑寫死--> <router-link to="/about">about</router-link> <!--動態綁定一個變量--> <router-link v-bind:to="document">document</router-link> <router-view></router-view> </div> </template> <script> export default { name: 'app', data () { return { document: '/document' } } } </script>
import Vue from 'vue' import Router from 'vue-router' // 引入路由模塊 import Home from '@/view/home' import About from '@/view/about' import Document from '@/view/document' Vue.use(Router) // 將路由模塊做爲插件使用 export default new Router({ mode: 'history', // 設置導航模式,默認是哈希模式,開發中通常使用history模式 routes: [ { path: '/home', name: 'home', component: Home }, { path: '/about', name: 'about', component: About }, { path: '/document', name: 'document', component: Document } ] })
router-link的tag屬性
這個屬性的使用方法是直接在router-link標籤上寫,好比下面tag=「span」,瀏覽器會將router-link編譯成你指定的標籤
<template> <div id="app"> <!--動態綁定對象的寫法--> <router-link v-bind:to="{path: '/home'}" tag="span">home</router-link> <!--直接將路徑寫死--> <router-link to="/about" tag="span">about</router-link> <!--動態綁定一個變量--> <router-link v-bind:to="document" tag="span">document</router-link> <router-view></router-view> </div> </template> <script> export default { name: 'app', data () { return { document: '/document' } } } </script>
exact屬性
當將某個路由設置爲根路徑的時候,無論以後訪問哪一個路由,這個根路由都會處於激活狀態,這時候須要用到exact這個屬性
<template> <div id="app"> <!--動態綁定對象的寫法--> <router-link v-bind:to="{path: '/'}" exact tag="span">home</router-link> <!--直接將路徑寫死--> <router-link to="/about" tag="span">about</router-link> <!--動態綁定一個變量--> <router-link v-bind:to="document" tag="span">document</router-link> <router-view></router-view> </div> </template> <script> export default { name: 'app', data () { return { document: '/document' } } } </script>
import Vue from 'vue' import Router from 'vue-router' // 引入路由模塊 import Home from '@/view/home' import About from '@/view/about' import Document from '@/view/document' Vue.use(Router) // 將路由模塊做爲插件使用 export default new Router({ mode: 'history', // 設置導航模式,默認是哈希模式,開發中通常使用history模式 routes: [ { path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: About }, { path: '/document', name: 'document', component: Document } ] })
配置當前選中的router-link的樣式
當前選中的router-link的樣式,有兩種設置,
第一種是全局設置:須要在路由配置裏面先配置linkActiveClass屬性,指定一個class類名
若是不配置linkActiveClass屬性,默認當前選中的那個router-link會加上這樣的一個類router-link-active
首先測試一下默認的,給默認的class加個樣式
<template> <div id="app"> <!--動態綁定對象的寫法--> <router-link v-bind:to="{path: '/'}" exact tag="span">home</router-link> <!--直接將路徑寫死--> <router-link to="/about" tag="span">about</router-link> <!--動態綁定一個變量--> <router-link v-bind:to="document" tag="span">document</router-link> <router-view></router-view> </div> </template> <script> export default { name: 'app', data () { return { document: '/document' } } } </script> <style scoped> .router-link-active{ color: red; } </style>
全局配置,在路由配置文件中加上linkActiveClass屬性,而且寫上相應的class樣式,配置了這個屬性以後,默認的router-link-active就不存在了
import Vue from 'vue' import Router from 'vue-router' // 引入路由模塊 import Home from '@/view/home' import About from '@/view/about' import Document from '@/view/document' Vue.use(Router) // 將路由模塊做爲插件使用 export default new Router({ mode: 'history', // 設置導航模式,默認是哈希模式,開發中通常使用history模式 linkActiveClass: 'is-active', routes: [ { path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: About }, { path: '/document', name: 'document', component: Document } ] })
<template> <div id="app"> <!--動態綁定對象的寫法--> <router-link v-bind:to="{path: '/'}" exact tag="span">home</router-link> <!--直接將路徑寫死--> <router-link to="/about" tag="span">about</router-link> <!--動態綁定一個變量--> <router-link v-bind:to="document" tag="span">document</router-link> <router-view></router-view> </div> </template> <script> export default { name: 'app', data () { return { document: '/document' } } } </script> <style scoped> .router-link-active{ color: red; } .is-active{ background-color: blue; } </style>
第二種是局部設置,局部會覆蓋全局,當點擊第一個的時候,使用的是全局配置,當點擊第二個,由於第二個在內行中有設置,因此內行的生效
<template> <div id="app"> <!--動態綁定對象的寫法--> <router-link v-bind:to="{path: '/'}" exact tag="span">home</router-link> <!--直接將路徑寫死--> <router-link to="/about" tag="span" active-class="active-class">about</router-link> <!--動態綁定一個變量--> <router-link v-bind:to="document" tag="span">document</router-link> <router-view></router-view> </div> </template> <script> export default { name: 'app', data () { return { document: '/document' } } } </script> <style scoped> .router-link-active{ color: red; } .is-active{ background-color: blue; } .active-class{ background-color: pink; } </style>
router-link事件處理
router-link的默認的事件處理是點擊,能夠經過router-link的一個event屬性來配置事件處理
下面將第一個router-link的事件配置成鼠標移入,將第二個router-link的事件配置成雙擊
<template> <div id="app"> <!--動態綁定對象的寫法--> <router-link v-bind:to="{path: '/'}" tag="span" event="mouseover">home</router-link> <!--直接將路徑寫死--> <router-link to="/about" tag="span" event="dblclick">about</router-link> <!--動態綁定一個變量--> <router-link v-bind:to="document" tag="span">document</router-link> <router-view></router-view> </div> </template> <script> export default { name: 'app', data () { return { document: '/document' } } } </script> <style scoped> .is-active{ background-color: blue; } </style>
router-view的配置項
router-view配置class樣式
<router-view>標籤內設置的class,加載到子組件的根標籤上,而且會拼上子組件裏面已經有的class
<template> <div id="app"> <!--動態綁定對象的寫法--> <router-link v-bind:to="{path: '/'}" tag="span" event="mouseover">home</router-link> <!--直接將路徑寫死--> <router-link to="/about" tag="span" event="dblclick">about</router-link> <!--動態綁定一個變量--> <router-link v-bind:to="document" tag="span">document</router-link> <router-view class="center"></router-view> </div> </template> <script> export default { name: 'app', data () { return { document: '/document' } } } </script> <style scoped> .is-active{ background-color: blue; } </style>
路由的重定向和別名
重定向的應用場景:當在瀏覽器輸入不存在的路由的時候,那麼做爲一個良好的網站,須要將頁面切換到一個已經配置好路由的頁面,或者是給出友好的提示
嵌套路由的使用
嵌套路由的使用場景:當一個路由裏面的組件還有路由的狀況下,就須要用到嵌套路由的寫法,下面簡單示例
<template> <div class="about"> <router-link v-bind:to="{path: '/about/hobby'}" tag="span">hobby</router-link> <router-link v-bind:to="{path: '/about/study'}" tag="span">study</router-link> <router-link v-bind:to="{path: '/about/work'}" tag="span">work</router-link> <router-view></router-view> </div> </template> <script type="text/ecmascript-6"> export default { name: 'about', data () { return {} } } </script> <style scoped></style>
import Vue from 'vue' import Router from 'vue-router' // 引入路由模塊 import Home from '@/view/home' import About from '@/view/about' import Document from '@/view/document' import Hobby from '@/components/about/hobby' import Study from '@/components/about/study' import Work from '@/components/about/work' Vue.use(Router) // 將路由模塊做爲插件使用 export default new Router({ mode: 'history', // 設置導航模式,默認是哈希模式,開發中通常使用history模式 routes: [ { path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: About, children: [ { path: '/about/hobby', name: 'hobby', component: Hobby }, { path: '/about/study', name: 'study', component: Study }, { path: '/about/work', name: 'work', component: Work } ] }, { path: '/document', name: 'document', component: Document } ] })
設置默認的子路由
直接將須要設置爲默認的子路由上的path改成空,而且將引導路徑改成父路由,而且使用精確匹配
而且若是設置了默認的子路由,那麼父路由上的name屬性就能夠不要了,能夠將這個name屬性放在默認的子路由上
<template> <div class="about"> <router-link v-bind:to="{path: '/about'}" tag="span">hobby</router-link> <router-link v-bind:to="{path: '/about/study'}" tag="span">study</router-link> <router-link v-bind:to="{path: '/about/work'}" tag="span">work</router-link> <router-view></router-view> </div> </template> <script type="text/ecmascript-6"> export default { name: 'about', data () { return {} } } </script> <style scoped></style>
import Vue from 'vue' import Router from 'vue-router' // 引入路由模塊 import Home from '@/view/home' import About from '@/view/about' import Document from '@/view/document' import Hobby from '@/components/about/hobby' import Study from '@/components/about/study' import Work from '@/components/about/work' Vue.use(Router) // 將路由模塊做爲插件使用 export default new Router({ mode: 'history', // 設置導航模式,默認是哈希模式,開發中通常使用history模式 routes: [ { path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: About, children: [ { path: '', name: 'about', component: Hobby }, { path: '/about/study', name: 'study', component: Study }, { path: '/about/work', name: 'work', component: Work } ] }, { path: '/document', name: 'document', component: Document } ] })
子路由配置成根路徑下
直接在子路由中加上一個/便可,這樣訪問子路由下的組件的時候,直接跟上子路由便可
<template> <div class="about"> <router-link v-bind:to="{path: '/about'}" tag="span">hobby</router-link> <router-link v-bind:to="{path: '/study'}" tag="span">study</router-link> <router-link v-bind:to="{path: '/work'}" tag="span">work</router-link> <router-view></router-view> </div> </template> <script type="text/ecmascript-6"> export default { name: 'about', data () { return {} } } </script> <style scoped></style>
import Vue from 'vue' import Router from 'vue-router' // 引入路由模塊 import Home from '@/view/home' import About from '@/view/about' import Document from '@/view/document' import Hobby from '@/components/about/hobby' import Study from '@/components/about/study' import Work from '@/components/about/work' Vue.use(Router) // 將路由模塊做爲插件使用 export default new Router({ mode: 'history', // 設置導航模式,默認是哈希模式,開發中通常使用history模式 routes: [ { path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: About, children: [ { path: '', name: 'about', component: Hobby }, { path: '/study', name: 'study', component: Study }, { path: '/work', name: 'work', component: Work } ] }, { path: '/document', name: 'document', component: Document } ] })
使用路由的name來引導路由
<template> <div class="about"> <router-link v-bind:to="{name: 'about'}" tag="span">hobby</router-link> <router-link v-bind:to="{name: 'study'}" tag="span">study</router-link> <router-link v-bind:to="{path: '/work'}" tag="span">work</router-link> <router-view></router-view> </div> </template> <script type="text/ecmascript-6"> export default { name: 'about', data () { return {} } } </script> <style scoped></style>
路由的命名
在同級同時展現多個視圖,而不是嵌套展現,也就是一個路由裏面展現兩個組件
路由的scrollBehavior方法
路由的scrollBehavior方法概述:該方法是路由下的一個方法,當點擊瀏覽器的前進和後退,或者點擊導航切換路由的時候會觸發這個方法
有三個參數,第一個是to(表示要進入的目標路由對象,就是要去向哪裏)
第二個參數form(表示離開的路由對象,就是從哪裏來的)
第三個參數savePosition(記錄滾動條的座標,點擊前進後退的時候纔會記錄值,不然是null或者undefined)
路由的scrollBehavior方法使用
import Vue from 'vue'
import Router from 'vue-router' // 引入路由模塊
import Home from '@/view/home'
import About from '@/view/about'
import Document from '@/view/document'
Vue.use(Router) // 將路由模塊做爲插件使用
export default new Router({
mode: 'history', // 設置導航模式,默認是哈希模式,開發中通常使用history模式
linkActiveClass: 'is-active',
scrollBehavior (to, from, savePosition) {
console.log(to)
console.log(from)
console.log(savePosition)
},
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/about',
name: 'about',
component: About
},
{
path: '/document',
name: 'document',
component: Document
}
]
})
路由的scrollBehavior方法的savePosition參數
這個參數能夠保存在瀏覽器上拉動的滾動條位置,當點擊前進後退的時候,會回到以前的滾動條位置
import Vue from 'vue'
import Router from 'vue-router' // 引入路由模塊
import Home from '@/view/home'
import About from '@/view/about'
import Document from '@/view/document'
Vue.use(Router) // 將路由模塊做爲插件使用
export default new Router({
mode: 'history', // 設置導航模式,默認是哈希模式,開發中通常使用history模式
linkActiveClass: 'is-active',
scrollBehavior (to, from, savePosition) {
console.log(to)
console.log(from)
console.log(savePosition)
if (savePosition) {
return savePosition
} else {
return {x: 0, y: 0}
}
},
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/about',
name: 'about',
component: About
},
{
path: '/document',
name: 'document',
component: Document
}
]
})
使用hash來定位到某個路由下的某個元素下(當是返回操做的時候這個功能就失效了)
首先須要到導航路徑上加上hash
<template> <div id="app" style="padding-top: 300px;"> <!--動態綁定對象的寫法--> <router-link v-bind:to="{path: '/'}" tag="span" event="mouseover">home</router-link> <!--直接將路徑寫死--> <span @click="aboutMe">about</span> <!--動態綁定一個變量--> <router-link to="document#abc" tag="span">document</router-link> <keep-alive> <router-view></router-view> </keep-alive> </div> </template> <script> export default { name: 'app', data () { return { document: '/document' } }, methods: { aboutMe () { this.$router.push({ path: '/about', query: { StraightProductId: 1 } }) } } } </script> <style scoped> .is-active{ background-color: blue; } </style>
而後標記這個元素
<template> <div class="document"> document <p id="abc">定位到這個位置</p> </div> </template> <script type="text/ecmascript-6"> export default { name: 'document', data () { return {} } } </script> <style scoped> .document{ height: 1900px; } </style>
而後再這個scrollBehavior方法內先判斷目標路由是否有hash,有的話就直接返回這個hash
import Vue from 'vue' import Router from 'vue-router' // 引入路由模塊 import Home from '@/view/home' import About from '@/view/about' import Document from '@/view/document' Vue.use(Router) // 將路由模塊做爲插件使用 export default new Router({ mode: 'history', // 設置導航模式,默認是哈希模式,開發中通常使用history模式 linkActiveClass: 'is-active', scrollBehavior (to, from, savePosition) { if (to.hash) { return { selector: to.hash } } }, routes: [ { path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: About }, { path: '/document', name: 'document', component: Document } ] })
運行結果顯示,當頂級document這個路由的時候跳轉到這個組件頁面而且定位到標記的元素
緩存路由組件對象
有這樣的一個需求,就是幾個tab選項,下面是不一樣的列表,那麼當來回切換的時候,正常狀況下,從一個路由切換到另一個路由,那麼以前的那個路由就會銷燬,當再切回來的時候又要從新的建立
當咱們的需求對數據的實時性沒有那麼高的時候,咱們能夠使用緩存路由組件,相反對數據的實時性比較高的狀況下,仍是使用正常的寫法
<template> <div> <input type="text" v-model="message" /> </div> </template> <script type="text/ecmascript-6"> export default { name: 'home', data () { return { message: '' } } } </script>
<template> <div id="app"> <!--動態綁定對象的寫法--> <router-link v-bind:to="{path: '/'}" tag="span" event="mouseover">home</router-link> <!--直接將路徑寫死--> <router-link to="/about" tag="span" event="dblclick">about</router-link> <!--動態綁定一個變量--> <router-link v-bind:to="document" tag="span">document</router-link> <keep-alive> <router-view></router-view> </keep-alive> </div> </template> <script> export default { name: 'app', data () { return { document: '/document' } } } </script> <style scoped> .is-active{ background-color: blue; } </style>
運行結果顯示,當我在home組件的input輸入了數據,切換到about組件後再切換會home組件,輸入框裏面的數據是還在的,若是是正常狀況下,input輸入框的數據會清空掉
向路由組件傳遞數據
從一個組件跳轉到另一個組件的時候,有個很常見的需求就是將某個列表組件的某個數據的id值傳遞到詳情組件,這時候一般經過路由上帶上參數,而後在詳情組件中獲取rul上面的參數
這裏改變一下路由的寫法,開發中一般使用一個點擊事件來觸發路由的跳轉,而不使用router-link
<template> <div id="app"> <!--動態綁定對象的寫法--> <router-link v-bind:to="{path: '/'}" tag="span" event="mouseover">home</router-link> <!--直接將路徑寫死--> <span @click="aboutMe">about</span> <!--動態綁定一個變量--> <router-link v-bind:to="document" tag="span">document</router-link> <keep-alive> <router-view></router-view> </keep-alive> </div> </template> <script> export default { name: 'app', data () { return { document: '/document' } }, methods: { aboutMe () { this.$router.push({ path: '/about', query: { StraightProductId: 1 } }) } } } </script> <style scoped> .is-active{ background-color: blue; } </style>
<template> <div class="about"> about </div> </template> <script type="text/ecmascript-6"> export default { name: 'about', data () { return { StraightProductId: null } }, created () { this.StraightProductId = this.$route.query.StraightProductId console.log(this.StraightProductId) } } </script> <style scoped></style>
運行結果顯示,當你切換到about路由的時候,後面就帶有了參數,而且在about組件中從路由的url上獲取到了這個參數
編程式路由導航
this.$router.push(path): 至關於點擊路由連接(能夠返回到當前路由界面)
<template> <div id="app"> <!--動態綁定對象的寫法--> <router-link v-bind:to="{path: '/'}" tag="span" event="mouseover">home</router-link> <!--直接將路徑寫死--> <span @click="aboutMe">about</span> <!--動態綁定一個變量--> <router-link v-bind:to="document" tag="span">document</router-link> <keep-alive> <router-view></router-view> </keep-alive> </div> </template> <script> export default { name: 'app', data () { return { document: '/document' } }, methods: { aboutMe () { this.$router.push({ path: '/about', query: { StraightProductId: 1 } }) } } } </script> <style scoped> .is-active{ background-color: blue; } </style>
this.$router.replace(path): 用新路由替換當前路由(不能夠返回到當前路由界面)
<template> <div id="app"> <!--動態綁定對象的寫法--> <router-link v-bind:to="{path: '/'}" tag="span" event="mouseover">home</router-link> <!--直接將路徑寫死--> <span @click="aboutMe">about</span> <!--動態綁定一個變量--> <router-link v-bind:to="document" tag="span">document</router-link> <keep-alive> <router-view></router-view> </keep-alive> </div> </template> <script> export default { name: 'app', data () { return { document: '/document' } }, methods: { aboutMe () { this.$router.replace({ path: '/about', query: { StraightProductId: 1 } }) } } } </script> <style scoped> .is-active{ background-color: blue; } </style>
this.$router.back(): 請求(返回)上一個記錄路由
<template> <div class="about"> <p @click="back">about</p> </div> </template> <script type="text/ecmascript-6"> export default { name: 'about', data () { return { StraightProductId: null } }, created () { this.StraightProductId = this.$route.query.StraightProductId console.log(this.StraightProductId) }, methods: { back () { this.$router.back() } } } </script> <style scoped></style>
this.$router.go(-1): 請求(返回)上一個記錄路由
<template> <div class="about"> <p @click="back">about</p> </div> </template> <script type="text/ecmascript-6"> export default { name: 'about', data () { return { StraightProductId: null } }, created () { this.StraightProductId = this.$route.query.StraightProductId console.log(this.StraightProductId) }, methods: { back () { this.$router.go(-1) } } } </script> <style scoped></style>
this.$router.go(1): 請求下一個記錄路由