1.背景介紹
vue router是vue.js官方的路由管理器,它和vue.js的核心深度集成,讓構(gòu)建單頁(yè)面應(yīng)用變得易如反掌,它的功能有:
嵌套的路由,或者是,視圖表;模塊化的,基于組件的路由配置;路由參數(shù),查詢,通配符,基于Vue.js過(guò)渡系統(tǒng)的視圖過(guò)渡效果,細(xì)粒度的導(dǎo)航控制;帶有自動(dòng)激活的CSS class的鏈接,HTML5歷史模式或者是hash模式,在IE9中自動(dòng)降級(jí);自定義的滾動(dòng)條行為。
面試官提問(wèn),你能說(shuō)出路由的概念嗎?能說(shuō)明一下vue-router的基本使用步驟嗎?或者讓你說(shuō)出vue-router的嵌套路由用法怎么用?
再次詢問(wèn)你vue-router如何實(shí)現(xiàn)動(dòng)態(tài)路由匹配用法呢?請(qǐng)說(shuō)出vue-router命名路由用法?請(qǐng)說(shuō)出vue-router編程式導(dǎo)航用法?
在實(shí)際業(yè)務(wù)中,去實(shí)現(xiàn)基于路由的方式。
2.快速入門
如何快速入門并掌握呢?了解路由的屬性配置說(shuō)明,如何頁(yè)面跳轉(zhuǎn),如何子路由-路由嵌套,路由的傳遞參數(shù),命名路由,命名視圖,重定向,別名,過(guò)渡動(dòng)畫,mode與404,路由的鉤子,路由的懶加載。
快速入門第一步安裝,vue-router是一個(gè)插件包,需要用npm來(lái)安裝。
npm install vue-router --save
vue-cli構(gòu)建項(xiàng)目。router/index.js中。
//?引入vue
import Vue from 'vue'
// 引入vue-router路由依賴
import Router from 'vue-router'
// 引入頁(yè)面組件,命名為HelloWorld
import HelloWorld from '@/components/HelloWorld'
// Vue全局使用Router
Vue.use(Router)
// 定義路由配置
export default new Router({
??routes:?[????????????????//配置路由
????{????????????????????????
? ? ? path:'/',? ? ? ? ? ? //鏈接路徑
??????name:?'HelloWorld',????????//路由名稱
??????component:?HelloWorld?????//對(duì)應(yīng)組件模板
? ? }
? ]
})
使用:main.js中
//?引入vue
import Vue from 'vue'
// 引入根組件
import App from './App'
// 引入路由配置
import router from './router'
// 關(guān)閉生產(chǎn)模式下給出的提示
Vue.config.productionTip = false
// 定義實(shí)例
new Vue({
? el:'#app',
? router,// 注入框架中
? components: { App },
? template:'<App/>'
})
頁(yè)面跳轉(zhuǎn):
<router-link?to="/">[顯示字段]</router-link>
<router-link to="/hello">hello</router-link>
this.$router.push('/xxx')
<button @click="goHome">回到首頁(yè)</button>
export default {
? ? name: 'app',
? ? methods: {
? ? ? ? goHome(){
? ? ? ? ? ? this.$router.push('/home');
? ? ? ? }
? ? }
}
//? 后退一步
this.$router.go(-1)
//?前進(jìn)一步
this.$router.go(1)
以下是常見(jiàn)的提問(wèn)加解答:
在開(kāi)發(fā)中,路由分后端路由和前端路由,后端路由是根據(jù)不同的用戶的url請(qǐng)求,返回不同的內(nèi)容,本質(zhì)是url請(qǐng)求地址與服務(wù)器資源之間的對(duì)應(yīng)關(guān)系。
3.后端路由
過(guò)程,瀏覽器請(qǐng)求url地址到后端服務(wù)器,請(qǐng)求url地址被后端路由攔截,服務(wù)器中有服務(wù)器資源內(nèi)容,是url地址所要請(qǐng)求的資源內(nèi)容,請(qǐng)求到服務(wù)器資源內(nèi)容被后端路由攔截傳遞給瀏覽器。
SPA,后端渲染是由性能問(wèn)題的,用戶與服務(wù)器有經(jīng)常提交多,后端路由就會(huì)導(dǎo)致網(wǎng)頁(yè)的頻繁刷新,導(dǎo)致性能問(wèn)題,就有了ajax前端渲染,SPA是單頁(yè)面應(yīng)用程序,整個(gè)網(wǎng)站只有一個(gè)頁(yè)面,內(nèi)容變化是通過(guò)ajax局部更新實(shí)現(xiàn),同時(shí)支持瀏覽器地址的前進(jìn)和后退操作,spa的實(shí)現(xiàn)原理之一是基于url地址上的hash。
注意,hash的變化會(huì)導(dǎo)致瀏覽器記錄訪問(wèn)歷史的變化,但是hash的變化不會(huì)觸發(fā)新的url請(qǐng)求,在實(shí)現(xiàn)spa過(guò)程中,最核心的技術(shù)就是前端路由。
4.前端路由
前端路由是根據(jù)不同的用戶事件,顯示不同的頁(yè)面內(nèi)容,本質(zhì)是用戶事件和事件處理函數(shù)之間的對(duì)應(yīng)關(guān)系,用戶觸發(fā)事件,響應(yīng)瀏覽器,瀏覽器中含有前端路由,事件處理函數(shù),用戶觸發(fā)事件給到前端路由,響應(yīng)事件處理函數(shù),事件函數(shù)渲染相應(yīng)內(nèi)容給用戶。
實(shí)現(xiàn)簡(jiǎn)單的前端路由是基于url中的hash實(shí)現(xiàn)的,點(diǎn)擊菜單時(shí)改變url的hash值,根據(jù)hash的變化控制組件的切換。
監(jiān)聽(tīng)window的onhashchange事件,根據(jù)獲取到的最新的hash值,切換要顯示的組件的名稱
window.onhashchange = function() {
?//?通過(guò)location.hash獲取到最新的hash值
}
簡(jiǎn)單的實(shí)例:
<div id="app">
//?切換組件的超連接
<a?href="#/zhuye">主頁(yè)</a>
<a href="#/keji>科技</a>
<a?href="#/caijing>財(cái)經(jīng)</a>
<a?href="#/yule">娛樂(lè)</a>
//?:is屬性指定的組件名稱,把對(duì)應(yīng)的組件渲染到component標(biāo)簽所在位置
//?可以把component標(biāo)簽當(dāng)前組件的占位符
<component?:is="keji"></component>
</div>
定義四個(gè)組件:
const zhuye = {
?template;?'<h1>da1</h1>'
}
const?keji = {
?template:?'<h1>da2</h1>'
}
const caijing = {
?template:'<h1>da3</h1>'
}
const yule = {
?template:'<h1>da4</h1>'
}
注冊(cè)組件
const?vm?=?new?Vue({
?el:'#app',
?data: {},
?// 注冊(cè)組件
?components: {
? zhuye,
??keji,
??caijing,
??yule
?}
?})
動(dòng)態(tài)切換
<component :is="comName"></component>
data: {
?comName: 'zhuye'
}
監(jiān)聽(tīng)window的onhashchange事件,根據(jù)獲取到的最新的hash值,切換要顯示的組件的名稱
window.onhashchange = function() {
?// 通過(guò)location.hash獲取到最新的hash值
?console.log(location.hash);
}
href="#/zhuye"
使用switch判斷
switch(location.hash.slice(1) {
?case '/zhuye':
? vm.comName = 'zhuye'
? break;
?case?'/keji':
? vm.comName = 'keji'
? break;
?case?'/caijing':
? vm.comName = 'caijing'
? break;
?case?'/yule':
? vm.comName = 'yule'
? break;
?}
5.vue-router路由管理器
vue router和vue.js的核心深度集成,可以方便的用于spa的應(yīng)用程序開(kāi)發(fā)
它的功能有:
支持HTML5歷史模式,和hash模式;支持嵌套路由;支持路由參數(shù),支持編程式路由,支持命名路由。
路由的進(jìn)階,導(dǎo)航守衛(wèi),路由元信息,過(guò)渡效果,數(shù)據(jù)獲取,滾動(dòng)行為,路由懶加載。
6.vue-router的基本使用
基本使用步驟,第一步,引入相關(guān)的庫(kù)文件,第二步,添加路由連接,第三步,添加路由填充位,第四步,定義路由組件,第五步,配置路由規(guī)則并創(chuàng)建路由實(shí)例,第六步,把路由掛載到vue根實(shí)例中。
router-link中,to表示目標(biāo)路由的鏈接,repalce,當(dāng)點(diǎn)擊時(shí)會(huì)調(diào)用router.replace()而不是router.push(),導(dǎo)航后不會(huì)留下history記錄。
<router-link?:to="{path:?'/a'}"?replace></router-link>
append,在當(dāng)前路徑前添加基路徑。我們從/a導(dǎo)航到一個(gè)相對(duì)路徑da,如果沒(méi)有配置append,則路徑為/da,如果配了,則為/a/da
<router-link?:to="{?path:?'/da'?}"?append></router-link>
基本使用步驟,第一步引入相關(guān)的庫(kù)文件
// 導(dǎo)入vue文件,為全局window對(duì)象掛載vue構(gòu)造函數(shù)
<script?src="./lib/vuexxxx.js"></script>
// 導(dǎo)入vue-router文件,為全局window對(duì)象掛載vuerouter構(gòu)造函數(shù)
<script src="./lib/vue-routerxxx.js"></script>
第二步添加路由鏈接
// router-link是vue中提供的標(biāo)簽,默認(rèn)會(huì)被渲染為a標(biāo)簽
//?to屬性默認(rèn)會(huì)被渲染成為 href 屬性
//?to?屬性的默認(rèn)會(huì)被渲染為#開(kāi)頭的hash地址
<router-link to="/user">User</router-link>
<router-link?to="/register">Register</router-link>
第三步添加路由填充位
// 路由填充位,叫做路由占位符
// 將來(lái)要通過(guò)路由規(guī)則匹配到的組件
//?會(huì)被渲染到router-view所在的位置
<router-view></router-view>
第四步添加定義路由組件,如果有兩個(gè)路由,添加兩個(gè)組件
var User = {
?template:'<div>user</div>'
}
var?Register = {
?template:?'<div>register</div>'
}
第五步,最重要,配置路由規(guī)則和創(chuàng)建路由實(shí)例
// 創(chuàng)建路由實(shí)例對(duì)象
var?router?=?new?VueRouter({
?//?routes 是路由規(guī)則數(shù)組
?routers: {
?//?每個(gè)路由規(guī)則都是一個(gè)配置對(duì)象,其中至少包含path和compontent兩個(gè)屬性
?//?path表示當(dāng)前路由規(guī)則匹配的hash地址
?{path:?'/user',?component: User},
?{path:?'/register',?component:?Register}
}}
第六步,把路由掛載到vue根實(shí)例中
new?Vue({
?el:?'#app',
?//為了能夠讓路由規(guī)則生效,必須把路由對(duì)象掛載到vue實(shí)例對(duì)象上
?router
});
7.路由重定向
路由重定向值的是,用戶在訪問(wèn)地址a的時(shí)候,強(qiáng)制用戶跳轉(zhuǎn)到地址c,從而展示特定的組件頁(yè)面,通過(guò)路由規(guī)則的redirect屬性,指定一個(gè)新的路由地址,可以方便地設(shè)置路由的重定向。
var router = new VueRouter({
?routers:?[
??//?其中,path表示需要被重定向的原地址,redirect表示將要被重定向的新地址
??{path;'/',?redirect: '/user'},
??{path:'/user', component: User},
??{path:'/register', component:Register}
?}
})
8.vue-router嵌套路由
嵌套路由,是什么呢?是父級(jí)別的路由下有子級(jí)別的路由。點(diǎn)擊父級(jí)路由鏈接顯示模板內(nèi)容,模板內(nèi)容又有子級(jí)別的路由鏈接,點(diǎn)擊子級(jí)別的路由顯示子級(jí)別的模板內(nèi)容。
第一步,創(chuàng)建父級(jí)路由組件模板,父級(jí)路由鏈接和父級(jí)組件路由的填充位
<p>
?<router-link?to="/xxx">xxx</router-link>
?<router-link?to="/xx">xx</router-link>
</p>
<div>
// 控制組件的顯示位置
<router-view></router-view>
</div>
第二步,創(chuàng)建子級(jí)別的路由模板,子級(jí)別路由鏈接,子級(jí)別路由填充位
const?Register = {
?template:`<div>
??<h1>dada</h1>
??<router-link?to="/register/xxx">xxx</router-link>
??<router-link?to="/register/xx">xx</router-link>
? // 子路由填充位置
??<router-view/>
?</div>`
}
第三步,嵌套路由的配置,父級(jí)路由通過(guò)children屬性配置子級(jí)路由
const?router = new VueRouter ({
?routes: [
? {path: '/user', component: User },
??{ path: '/reg',
????component: Register,
????//?通過(guò)children屬性,為/register添加子路由規(guī)則
????children: [
?????{path:?'/reg/p1',?component: p1},
?????{path: '/reg/p2', component: p2}
????]
???}
??]
?})
創(chuàng)建子路由鏈接,子路由占位符的時(shí)候,別忘記了要寫子組件的代碼。
comst?p1 = {
?template:?'<h1>da</h1>'
}
9.vue-router動(dòng)態(tài)路由匹配
什么是動(dòng)態(tài)路由匹配,為啥要?jiǎng)討B(tài)路由匹配?
場(chǎng)景如下
<router-link?to="/user/1">da1</router-link>
<router-link?to="/user/2">da2</router-link>
<router-link?to="/user/3">da3</router-link>
{?path:?'/user/1,?component:?user}
{?path:?'/user/2,?component:?user}
{?path:?'/user/3,?component:?user}
動(dòng)態(tài)參數(shù), :id
var router = new VueRouter({
?routes: [
? // 動(dòng)態(tài)路徑參數(shù) 冒號(hào)開(kāi)頭
??{path:?'/user/:id', component: User }
?}
})
const?User?=?{
?// 路由組件中通過(guò) $route.params獲取路由參數(shù)
?template:?'<div>U?{{?$route.params.id?}} </div>'
}
路由組件傳遞參數(shù)props,將props的值設(shè)置為布爾類型
const router = new VueRouter({
?routes: [
??//?如果props被設(shè)置為true, route.params將會(huì)被設(shè)置為組件屬性
??{path:?'/user/:id',?component:?User,?params: true }
?]
})
const User = {
?props:?['id'],?//?使用props接收路由參數(shù)
?template: '<div>da {{id}} </div>' // 使用路由參數(shù)
}
props的值可以為對(duì)象類型的參數(shù),傳遞動(dòng)態(tài)參數(shù)
const?router?=?new?VueRouter({
?routes: [
??//?如果props是一個(gè)對(duì)象,它會(huì)被按原樣設(shè)置為組件屬性
??{?path:?'/user/:id',?component:?User,?props:?{?name:?'dada',?age:?12?}}
?]
})
const?User = {
?props:?['name','age'],
?template:?`<div>?{{name}}?+ {{age}} </div>`
}
props的值為函數(shù)類型的參數(shù)
const router = new VueRouter({
?routes: {
??//?如果props是一個(gè)函數(shù),則這個(gè)函數(shù)接收?route?對(duì)象為自己的形參
??{?path:?'/user/:id',
????component:?Use,
????props:?route?=>?{{?name:?'dada',?age:?12, id: route.params.id }}}
???}
??})
??const?User = {
???props:?{'name',?'age',?'id'},
???template:?`<div>?{{name}}?+?{{?age?}}?+?{{id}} </div>`
??}
10.什么叫做命名路由
路由的name可以指定命名名稱,不用寫path。命名路由的配置規(guī)則
// 路由導(dǎo)航
const router = new VueRouter({
?routes: [
? {
? path:'/user/id',
? name:'user',
???component: User
??}
?]
})
<router-link :to="{name:'user', params: {id:1} }">dada</router-link>
router.push({name:'user',?params:?{id:1} }}
編程時(shí)導(dǎo)航,第一種,聲明式導(dǎo)航是通過(guò)點(diǎn)擊鏈接實(shí)現(xiàn)導(dǎo)航的方式,如網(wǎng)頁(yè)中的a標(biāo)簽或是vue中router-link標(biāo)簽;第二種,編程式導(dǎo)航通過(guò)JavaScript的形式api實(shí)現(xiàn)導(dǎo)航的方式,如網(wǎng)頁(yè)中的location.href。
// 編程式導(dǎo)航
this.$router.push('hash地址'
this.$router.go(n)
const User = {
?template:?'<div><button?@click="goButton">跳轉(zhuǎn)</button></div>',
?methods: {
? goButton: function(){
???//?用編程的方式控制路由跳轉(zhuǎn)
???this.$router.push('/register');
??}
?}
}
const da = {
?template:`<div>
??<button?@click="goBack">后退</button>
??</div>`
??methods: {
???goBack() {
??? this.$router.go(-1)
???}
??}
?}
router.push()方法
router.push('/dada')
router.push(?{?path:?'/dada' })
router.push(?{?name:?'/dada', params;?{ id:?1?}?})
router.push( { path: '/dada', query: {name:'dada'} })
案例,多多使用,路由的基礎(chǔ)語(yǔ)法,嵌套路由,路由的重定向,路由的傳參,編程式導(dǎo)航等。
vue-router默認(rèn)為hash模式,使用url的hash來(lái)模擬一個(gè)完整url,當(dāng)改變url時(shí),頁(yè)面不會(huì)重新加載。
const router = new VueRouter({
mode: 'history',?
routes: [...]
})