1.背景介紹
vue router是vue.js官方的路由管理器,它和vue.js的核心深度集成棺滞,讓構(gòu)建單頁面應(yīng)用變得易如反掌裁蚁,它的功能有:
嵌套的路由矢渊,或者是,視圖表枉证;模塊化的矮男,基于組件的路由配置;路由參數(shù)室谚,查詢毡鉴,通配符,基于Vue.js過渡系統(tǒng)的視圖過渡效果秒赤,細(xì)粒度的導(dǎo)航控制猪瞬;帶有自動激活的CSS class的鏈接,HTML5歷史模式或者是hash模式入篮,在IE9中自動降級陈瘦;自定義的滾動條行為。
面試官提問潮售,你能說出路由的概念嗎痊项?能說明一下vue-router的基本使用步驟嗎?或者讓你說出vue-router的嵌套路由用法怎么用酥诽?
再次詢問你vue-router如何實現(xiàn)動態(tài)路由匹配用法呢鞍泉?請說出vue-router命名路由用法?請說出vue-router編程式導(dǎo)航用法肮帐?
在實際業(yè)務(wù)中咖驮,去實現(xiàn)基于路由的方式。
2.快速入門
如何快速入門并掌握呢训枢?了解路由的屬性配置說明游沿,如何頁面跳轉(zhuǎn),如何子路由-路由嵌套肮砾,路由的傳遞參數(shù),命名路由袋坑,命名視圖仗处,重定向,別名枣宫,過渡動畫婆誓,mode與404,路由的鉤子也颤,路由的懶加載洋幻。
快速入門第一步安裝,vue-router是一個插件包翅娶,需要用npm來安裝文留。
npm install vue-router --save
vue-cli構(gòu)建項目好唯。router/index.js中。
//?引入vue
import Vue from 'vue'
// 引入vue-router路由依賴
import Router from 'vue-router'
// 引入頁面組件燥翅,命名為HelloWorld
import HelloWorld from '@/components/HelloWorld'
// Vue全局使用Router
Vue.use(Router)
// 定義路由配置
export default new Router({
??routes:?[????????????????//配置路由
????{????????????????????????
? ? ? path:'/',? ? ? ? ? ? //鏈接路徑
??????name:?'HelloWorld',????????//路由名稱
??????component:?HelloWorld?????//對應(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
// 定義實例
new Vue({
? el:'#app',
? router,// 注入框架中
? components: { App },
? template:'<App/>'
})
頁面跳轉(zhuǎn):
<router-link?to="/">[顯示字段]</router-link>
<router-link to="/hello">hello</router-link>
this.$router.push('/xxx')
<button @click="goHome">回到首頁</button>
export default {
? ? name: 'app',
? ? methods: {
? ? ? ? goHome(){
? ? ? ? ? ? this.$router.push('/home');
? ? ? ? }
? ? }
}
//? 后退一步
this.$router.go(-1)
//?前進(jìn)一步
this.$router.go(1)
以下是常見的提問加解答:
在開發(fā)中骑篙,路由分后端路由和前端路由,后端路由是根據(jù)不同的用戶的url請求森书,返回不同的內(nèi)容靶端,本質(zhì)是url請求地址與服務(wù)器資源之間的對應(yīng)關(guān)系。
3.后端路由
過程凛膏,瀏覽器請求url地址到后端服務(wù)器杨名,請求url地址被后端路由攔截,服務(wù)器中有服務(wù)器資源內(nèi)容猖毫,是url地址所要請求的資源內(nèi)容台谍,請求到服務(wù)器資源內(nèi)容被后端路由攔截傳遞給瀏覽器。
SPA鄙麦,后端渲染是由性能問題的典唇,用戶與服務(wù)器有經(jīng)常提交多,后端路由就會導(dǎo)致網(wǎng)頁的頻繁刷新胯府,導(dǎo)致性能問題介衔,就有了ajax前端渲染,SPA是單頁面應(yīng)用程序骂因,整個網(wǎng)站只有一個頁面炎咖,內(nèi)容變化是通過ajax局部更新實現(xiàn),同時支持瀏覽器地址的前進(jìn)和后退操作寒波,spa的實現(xiàn)原理之一是基于url地址上的hash乘盼。
注意,hash的變化會導(dǎo)致瀏覽器記錄訪問歷史的變化俄烁,但是hash的變化不會觸發(fā)新的url請求绸栅,在實現(xiàn)spa過程中,最核心的技術(shù)就是前端路由页屠。
4.前端路由
前端路由是根據(jù)不同的用戶事件粹胯,顯示不同的頁面內(nèi)容,本質(zhì)是用戶事件和事件處理函數(shù)之間的對應(yīng)關(guān)系辰企,用戶觸發(fā)事件风纠,響應(yīng)瀏覽器,瀏覽器中含有前端路由牢贸,事件處理函數(shù)竹观,用戶觸發(fā)事件給到前端路由,響應(yīng)事件處理函數(shù),事件函數(shù)渲染相應(yīng)內(nèi)容給用戶臭增。
實現(xiàn)簡單的前端路由是基于url中的hash實現(xiàn)的懂酱,點擊菜單時改變url的hash值,根據(jù)hash的變化控制組件的切換速址。
監(jiān)聽window的onhashchange事件玩焰,根據(jù)獲取到的最新的hash值,切換要顯示的組件的名稱
window.onhashchange = function() {
?//?通過location.hash獲取到最新的hash值
}
簡單的實例:
<div id="app">
//?切換組件的超連接
<a?href="#/zhuye">主頁</a>
<a href="#/keji>科技</a>
<a?href="#/caijing>財經(jīng)</a>
<a?href="#/yule">娛樂</a>
//?:is屬性指定的組件名稱芍锚,把對應(yīng)的組件渲染到component標(biāo)簽所在位置
//?可以把component標(biāo)簽當(dāng)前組件的占位符
<component?:is="keji"></component>
</div>
定義四個組件:
const zhuye = {
?template昔园;?'<h1>da1</h1>'
}
const?keji = {
?template:?'<h1>da2</h1>'
}
const caijing = {
?template:'<h1>da3</h1>'
}
const yule = {
?template:'<h1>da4</h1>'
}
注冊組件
const?vm?=?new?Vue({
?el:'#app',
?data: {},
?// 注冊組件
?components: {
? zhuye,
??keji,
??caijing,
??yule
?}
?})
動態(tài)切換
<component :is="comName"></component>
data: {
?comName: 'zhuye'
}
監(jiān)聽window的onhashchange事件,根據(jù)獲取到的最新的hash值并炮,切換要顯示的組件的名稱
window.onhashchange = function() {
?// 通過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)用程序開發(fā)
它的功能有:
支持HTML5歷史模式,和hash模式逃魄;支持嵌套路由荤西;支持路由參數(shù),支持編程式路由伍俘,支持命名路由邪锌。
路由的進(jìn)階,導(dǎo)航守衛(wèi)癌瘾,路由元信息觅丰,過渡效果,數(shù)據(jù)獲取妨退,滾動行為妇萄,路由懶加載。
6.vue-router的基本使用
基本使用步驟咬荷,第一步冠句,引入相關(guān)的庫文件,第二步幸乒,添加路由連接懦底,第三步,添加路由填充位罕扎,第四步基茵,定義路由組件,第五步壳影,配置路由規(guī)則并創(chuàng)建路由實例,第六步弥臼,把路由掛載到vue根實例中宴咧。
router-link中,to表示目標(biāo)路由的鏈接径缅,repalce掺栅,當(dāng)點擊時會調(diào)用router.replace()而不是router.push()烙肺,導(dǎo)航后不會留下history記錄。
<router-link?:to="{path:?'/a'}"?replace></router-link>
append氧卧,在當(dāng)前路徑前添加基路徑桃笙。我們從/a導(dǎo)航到一個相對路徑da,如果沒有配置append沙绝,則路徑為/da搏明,如果配了,則為/a/da
<router-link?:to="{?path:?'/da'?}"?append></router-link>
基本使用步驟闪檬,第一步引入相關(guān)的庫文件
// 導(dǎo)入vue文件星著,為全局window對象掛載vue構(gòu)造函數(shù)
<script?src="./lib/vuexxxx.js"></script>
// 導(dǎo)入vue-router文件,為全局window對象掛載vuerouter構(gòu)造函數(shù)
<script src="./lib/vue-routerxxx.js"></script>
第二步添加路由鏈接
// router-link是vue中提供的標(biāo)簽粗悯,默認(rèn)會被渲染為a標(biāo)簽
//?to屬性默認(rèn)會被渲染成為 href 屬性
//?to?屬性的默認(rèn)會被渲染為#開頭的hash地址
<router-link to="/user">User</router-link>
<router-link?to="/register">Register</router-link>
第三步添加路由填充位
// 路由填充位虚循,叫做路由占位符
// 將來要通過路由規(guī)則匹配到的組件
//?會被渲染到router-view所在的位置
<router-view></router-view>
第四步添加定義路由組件,如果有兩個路由样傍,添加兩個組件
var User = {
?template:'<div>user</div>'
}
var?Register = {
?template:?'<div>register</div>'
}
第五步横缔,最重要,配置路由規(guī)則和創(chuàng)建路由實例
// 創(chuàng)建路由實例對象
var?router?=?new?VueRouter({
?//?routes 是路由規(guī)則數(shù)組
?routers: {
?//?每個路由規(guī)則都是一個配置對象衫哥,其中至少包含path和compontent兩個屬性
?//?path表示當(dāng)前路由規(guī)則匹配的hash地址
?{path:?'/user',?component: User},
?{path:?'/register',?component:?Register}
}}
第六步茎刚,把路由掛載到vue根實例中
new?Vue({
?el:?'#app',
?//為了能夠讓路由規(guī)則生效,必須把路由對象掛載到vue實例對象上
?router
});
7.路由重定向
路由重定向值的是炕檩,用戶在訪問地址a的時候斗蒋,強(qiáng)制用戶跳轉(zhuǎn)到地址c,從而展示特定的組件頁面笛质,通過路由規(guī)則的redirect屬性泉沾,指定一個新的路由地址,可以方便地設(shè)置路由的重定向妇押。
var router = new VueRouter({
?routers:?[
??//?其中跷究,path表示需要被重定向的原地址,redirect表示將要被重定向的新地址
??{path敲霍;'/',?redirect: '/user'},
??{path:'/user', component: User},
??{path:'/register', component:Register}
?}
})
8.vue-router嵌套路由
嵌套路由俊马,是什么呢?是父級別的路由下有子級別的路由肩杈。點擊父級路由鏈接顯示模板內(nèi)容柴我,模板內(nèi)容又有子級別的路由鏈接,點擊子級別的路由顯示子級別的模板內(nèi)容扩然。
第一步艘儒,創(chuàng)建父級路由組件模板,父級路由鏈接和父級組件路由的填充位
<p>
?<router-link?to="/xxx">xxx</router-link>
?<router-link?to="/xx">xx</router-link>
</p>
<div>
// 控制組件的顯示位置
<router-view></router-view>
</div>
第二步,創(chuàng)建子級別的路由模板界睁,子級別路由鏈接觉增,子級別路由填充位
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>`
}
第三步,嵌套路由的配置翻斟,父級路由通過children屬性配置子級路由
const?router = new VueRouter ({
?routes: [
? {path: '/user', component: User },
??{ path: '/reg',
????component: Register,
????//?通過children屬性逾礁,為/register添加子路由規(guī)則
????children: [
?????{path:?'/reg/p1',?component: p1},
?????{path: '/reg/p2', component: p2}
????]
???}
??]
?})
創(chuàng)建子路由鏈接,子路由占位符的時候访惜,別忘記了要寫子組件的代碼嘹履。
comst?p1 = {
?template:?'<h1>da</h1>'
}
9.vue-router動態(tài)路由匹配
什么是動態(tài)路由匹配,為啥要動態(tài)路由匹配疾牲?
場景如下
<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}
動態(tài)參數(shù)植捎, :id
var router = new VueRouter({
?routes: [
? // 動態(tài)路徑參數(shù) 冒號開頭
??{path:?'/user/:id', component: User }
?}
})
const?User?=?{
?// 路由組件中通過 $route.params獲取路由參數(shù)
?template:?'<div>U?{{?$route.params.id?}} </div>'
}
路由組件傳遞參數(shù)props,將props的值設(shè)置為布爾類型
const router = new VueRouter({
?routes: [
??//?如果props被設(shè)置為true, route.params將會被設(shè)置為組件屬性
??{path:?'/user/:id',?component:?User,?params: true }
?]
})
const User = {
?props:?['id'],?//?使用props接收路由參數(shù)
?template: '<div>da {{id}} </div>' // 使用路由參數(shù)
}
props的值可以為對象類型的參數(shù)阳柔,傳遞動態(tài)參數(shù)
const?router?=?new?VueRouter({
?routes: [
??//?如果props是一個對象焰枢,它會被按原樣設(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是一個函數(shù),則這個函數(shù)接收?route?對象為自己的形參
??{?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} }}
編程時導(dǎo)航,第一種霍转,聲明式導(dǎo)航是通過點擊鏈接實現(xiàn)導(dǎo)航的方式荐绝,如網(wǎng)頁中的a標(biāo)簽或是vue中router-link標(biāo)簽;第二種避消,編程式導(dǎo)航通過JavaScript的形式api實現(xiàn)導(dǎo)航的方式低滩,如網(wǎng)頁中的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ǔ)語法纱意,嵌套路由婶溯,路由的重定向,路由的傳參偷霉,編程式導(dǎo)航等迄委。
vue-router默認(rèn)為hash模式,使用url的hash來模擬一個完整url类少,當(dāng)改變url時叙身,頁面不會重新加載。
const router = new VueRouter({
mode: 'history',?
routes: [...]
})