Vue Router 學(xué)習(xí)
前言
隨著ajax興起,頁(yè)面請(qǐng)求越來(lái)越多,是用來(lái)處理單頁(yè)應(yīng)用 SPA(single page web application)的不二之選
SPA應(yīng)用特點(diǎn)體現(xiàn)在如下:
- 頁(yè)面交互是無(wú)刷新
- 頁(yè)面的跳轉(zhuǎn)也是無(wú)刷新的
原理是 匹配不同的 url 路徑夺颤,進(jìn)行解析,然后動(dòng)態(tài)的渲染出區(qū)域 html 內(nèi)容
每當(dāng)切換路由的時(shí)候具伍,在DOM中刪除上一個(gè)路由節(jié)點(diǎn)(from
)钞脂,渲染一個(gè)新的節(jié)點(diǎn)(to
)-- 可使用緩存路由
keep-alive
,從而不使用
這種銷(xiāo)毀再創(chuàng)建的模式
可是url 每次變化的時(shí)候,都會(huì)造成頁(yè)面的刷新棘脐,
那么解決辦法就是在改變 url 的情況下斜筐,保證頁(yè)面的不刷新
2014年以前前端路由是通過(guò)hash模式進(jìn)行
通過(guò)類(lèi)似這樣 http://www.xxx.com/#login
這種 #的后面部分 ,后面的 hash 值會(huì)發(fā)生變化
并不會(huì)導(dǎo)致瀏覽器向服務(wù)器發(fā)出請(qǐng)求蛀缝,瀏覽器不發(fā)出請(qǐng)求顷链,也就不會(huì)刷新頁(yè)面。
另外每次 hash 值的變化屈梁,還會(huì)觸發(fā)
hashchange
事件, 從而我們可知hash 發(fā)生了哪些變化*** window.onhashchange***
然后我們可以監(jiān)聽(tīng)
hashchange
來(lái)實(shí)現(xiàn)頁(yè)面的更新
14年后HTML5 標(biāo)準(zhǔn)發(fā)布多了兩個(gè)API `pushState· `replaceState`
至此url路徑變得美觀(guān)嗤练。(如果你愿意使用 vue-router 的同時(shí)開(kāi)啟 history
模式的話(huà))
mode:'history'
Vue Router 在模塊化編程中的用法
現(xiàn)在來(lái)配置一個(gè)簡(jiǎn)單路由
加入路由跳轉(zhuǎn)頁(yè)面的組件都創(chuàng)建在 src 目錄下的 view下比較好
view 下為頁(yè)面級(jí)組件,一般不復(fù)用在讶,一般引用 components下面的小組件
components 下為小組件煞抬,常用組件,一般會(huì)復(fù)用
router
名詞构哺,路由器(發(fā)出動(dòng)作者)
route
名詞革答,路由(所走的路徑)
routes
名詞(復(fù)數(shù))(代表一組路由路徑)
src 目錄下創(chuàng)建一個(gè)文件夾為
router
在router 文件夾下 創(chuàng)建
index.js
文件-
main.js
中導(dǎo)入 且聲明使用import router from './router' // 省略了 /index.js 這是因?yàn)閣ebpack默認(rèn) index true
new Vue({ router, //實(shí)例中使用 store, render: h => h(App) }).$mount('#app')
-
編寫(xiě)
index.js
文件import VueRouter from 'vue-router' //導(dǎo)入前 記得導(dǎo)入前置 vue
Vue.use(VueRouter) // 使用
-
產(chǎn)生一個(gè)對(duì)象并向外暴露
export default new VueRouter({ })
-
在
routes
中配置n
個(gè)路由export default new VueRouter({ mode:'history', routes: [ //多條對(duì)象,理因是一個(gè)數(shù)組 { // 第1條路由 path: '/', component: xxx // 對(duì)應(yīng)映射的組件名 請(qǐng)?jiān)谑褂弥跋葘?dǎo)入組件 }, { // 第2條路由 path: '/xxx', } ] })
在
App
組件中的模板中 在需要點(diǎn)擊跳轉(zhuǎn)路由的地方指定router-link
<router-link to="/xxx">這里配置要顯示的文本曙强,相當(dāng)于 a 連接</router-link>
to 里面的參數(shù)一定要寫(xiě)
routers
中的path
對(duì)應(yīng)一致
- 在指定變化的部分中加入
router-view
<templete>
<div id='app'>
<nav>
<router-link to="">Home</router-link>
<router-link to="">About</router-link>
</nav>
<div class="main-body">
<router-view></router-view> <!--這里是需要變化的部分-->
</div>
</div>
</templete>
現(xiàn)在來(lái)配置一個(gè)嵌套路由
配置嵌套路由的時(shí)候残拐,會(huì)出現(xiàn)如下情況:
下面這些問(wèn)題,好像是我當(dāng)初
router-link
里面的to
與index.js
里面的路由映射對(duì)應(yīng)>不上所以才產(chǎn)生的問(wèn)題, 請(qǐng)仔細(xì)檢查自己有沒(méi)有配錯(cuò)碟嘴!
指定的 層級(jí)嵌套路由路徑不正確 (時(shí)刻注意
path
中最左邊的/
代表根路徑溪食,請(qǐng)寫(xiě)全,/father/child
,或者 直接省略為xxx
)
- 在加入子路由嵌套的時(shí)候使用簡(jiǎn)寫(xiě)
path
會(huì)發(fā)生問(wèn)題娜扇,點(diǎn)擊子組件后不顯示错沃,(這個(gè)問(wèn)題發(fā)生在 父組件的path
為/
的時(shí)候),將/
更改為具體的名稱(chēng)(或者老老實(shí)實(shí)寫(xiě)全路徑)const routes = [ { path: '/', name: 'home', component: Home, children: [ { path: '/home/news', // 靠近path 最左側(cè)的那個(gè) / 代表根路徑 name: 'news', component: News }, { path: 'message', // 這個(gè)時(shí)候簡(jiǎn)寫(xiě)會(huì)出現(xiàn)問(wèn)題边败,點(diǎn)擊會(huì)渲染不出,必須寫(xiě)全/home/message name: 'message', component: Message } ] }, { path: '/about', name: 'about', // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') } ]
將
/
修改為具體路徑可解決{ path: '/home', //修改在這里 name: 'home', component: Home, children: [ { path: '/home/news', name: 'news', component: News }, { path: 'message', // 簡(jiǎn)寫(xiě)沒(méi)問(wèn)題了 name: 'message', component: Message } ] },
在寫(xiě)path的時(shí)候捎废,如果在 router-link 中用到了該 path笑窜,請(qǐng)一定對(duì)照寫(xiě)一致,
在寫(xiě)name的時(shí)候登疗,必須寫(xiě)引入的組件中 組件的名字排截,如:
export default { name: 'Login', //假設(shè)這是 登陸組件 }
在路由中配置:
{ path:'/login', //隨意指定 name:'Login', //不能隨意指定,必須大小寫(xiě)一致辐益,寫(xiě)成login就不行断傲,vue默認(rèn)按照組件名稱(chēng)渲染路由 component:Login }
緩存路由組件
用來(lái)保持組件的狀態(tài),在
tab
選項(xiàng)卡中跳轉(zhuǎn)有時(shí)候需要查看下上一個(gè)tab
的信息智政,但是之前的數(shù)據(jù)是從后臺(tái)獲取來(lái)的认罩,這個(gè)時(shí)候不需要再次請(qǐng)求數(shù)據(jù)(實(shí)時(shí)性要求比較低的),減小服務(wù)器壓力续捂,來(lái)使用
keep-alive
保持垦垂,緩存這個(gè)組件對(duì)象
<keep-alive>
<router-view></router-view>
</keep-alive>
使用編程式路由
意思就是不使用
<router-link> xxx </router-link>
,這樣的點(diǎn)擊跳轉(zhuǎn),在代碼執(zhí)行的時(shí)候決定跳轉(zhuǎn)路由
this.$router.push('/toPath')
使用 watch
來(lái)監(jiān)視路由的最新變化
vue中牙瓢,獲取實(shí)時(shí)最新的狀態(tài)的方法就是 watch
如果有以下需求:
左邊的樹(shù)結(jié)構(gòu)是 發(fā)起ajax 請(qǐng)求成功后渲染出來(lái)的劫拗,
左邊的每一個(gè)樹(shù)節(jié)點(diǎn)node 都有唯一的一個(gè) Key標(biāo)識(shí)
當(dāng)點(diǎn)擊某一個(gè)node的時(shí)候,進(jìn)行路由跳轉(zhuǎn)矾克,需要傳遞對(duì)應(yīng)的 Key標(biāo)識(shí)改變路由跳轉(zhuǎn)
結(jié)構(gòu)和需求看起來(lái)像下面這樣:
路由跳轉(zhuǎn)時(shí)攜帶參數(shù) params
(此處沒(méi)用 query
來(lái)攜帶參數(shù))
params
與 query
的區(qū)別請(qǐng)點(diǎn)擊
this.$router.push({name:'ModuleConfig',params:{index:n}})
// 得到 n 的值不在這里提出
右邊的router-view
區(qū)域中 使用watch
data(){
return{
index: this.$route.params.index
}
}
好像有說(shuō)法:
router
只負(fù)責(zé)寫(xiě)(傳)
route
只負(fù)責(zé)讀(纫晨丁)
'$route'(to,from){
this.index = to.params.index //獲取實(shí)時(shí)最新的 后綴 index,然后index 變化時(shí)胁附,整個(gè)表單變化
}
// 左值 index 定義在 data 中(普通屬性)
// 右值 在路由跳轉(zhuǎn)的攜帶參數(shù)中取出
router
中的 index.js
修改配置
const routes = [
{
path:'/ModuleConfig/:index', //要對(duì)應(yīng)
name:'ModuleConfig',
component:ModuleConfig,
}
]
這里還可以將
index
定義成computed
屬性
computed:{
index(){
return this.$route.params.index
}
}
如果你需要分別拿到
oldvalue
酒繁,newvalue
,那顯然watch
更合適
watch
更像是為屬性改變的前后定義的一個(gè)鉤子函數(shù)控妻,可以點(diǎn)擊此處 參考查看我的另一篇文章中寫(xiě)到的區(qū)別
以后再慢慢更新,最后說(shuō)下:
任何時(shí)候都參照下 Vue 風(fēng)格指南都是好的州袒。比如
static
與assets
文件夾的區(qū)別,又比如view
與components
文件夾的區(qū)別,說(shuō)不定每次 vue-cli 的更新都會(huì)帶來(lái)vue ui
構(gòu)建項(xiàng)目后的文件夾不一致呢饼暑? GO to Vue 風(fēng)格指南