http://router.vuejs.org/zh-cn/
動(dòng)態(tài)路由匹配(路由傳參)
我們經(jīng)常需要把某種模式匹配到的所有路由瀑志,全都映射到同個(gè)組件沸柔。例如坞笙,我們有一個(gè) User
組件闷供,對(duì)于所有 ID 各不相同的用戶(hù)仍稀,都要使用這個(gè)組件來(lái)渲染拳芙。那么假勿,我們可以在 vue-router
的路由路徑中使用『動(dòng)態(tài)路徑參數(shù)』(dynamic segment)來(lái)達(dá)到這個(gè)效果:
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User }
]
})
現(xiàn)在呢,像 /user/foo
和 /user/bar
都將映射到相同的路由态鳖。
傳參
在需要進(jìn)行頁(yè)面跳轉(zhuǎn)傳值的地方转培,傳遞參數(shù),在子路由頁(yè)面中可以接收到
使用router-link
標(biāo)簽的to屬性進(jìn)行參數(shù)的傳遞
聲明式傳參數(shù) <router-link to="..."></router-link>
<li v-for="(item, index) in data">
<router-link :to="'/user/' + item.activity.name">
<img :src="item.activity.img" :style="{ width: '200px' }" alt="">
<p>{{ item.activity.name }}</p>
</router-link>
</li>
編程式傳參 $router.push()
<li v-for="(item, index) in data" @click="push(item.activity)">
<img :src="item.activity.img" :style="{ width: '200px' }" alt="">
<p>{{ item.activity.name }}</p>
</li>
push(item) {
// 在方法中進(jìn)行路由跳轉(zhuǎn)浆竭,并傳遞參數(shù)
// this.$router.push('/listdetail/' + item.name)
// 帶查詢(xún)參數(shù)浸须,變成 /listdetail/abc?plan=private
this.$router.push({
path: '/listdetail/' + item.name, // 路徑
query: { // 查詢(xún)參數(shù)
plan: 'private'
}
})
}
接參
使用$route.params
屬性接收參數(shù)
<template lang="html">
<div id="list-detail">
<!-- 在模板中直接接收 -->
<h2>{{ $route.params.id }}</h2>
<h2>{{ id }}</h2>
</div>
</template>
<script>
export default {
data() {
return { // 在數(shù)據(jù)中接收
id: this.$route.params.id
}
}
}
</script>
返回按鈕
使用history.back()可以返回上一頁(yè)
注意:不可以直接寫(xiě)在@click中惨寿,需要寫(xiě)在methods內(nèi)部
<button @click="back">返回</button>
methods: {
back() {
history.back()
}
}
響應(yīng)路由參數(shù)的變化
提醒一下,當(dāng)使用路由參數(shù)時(shí)删窒,例如從 /user/foo
導(dǎo)航到 user/bar
裂垦,原來(lái)的組件實(shí)例會(huì)被復(fù)用。因?yàn)閮蓚€(gè)路由都渲染同個(gè)組件肌索,比起銷(xiāo)毀再創(chuàng)建蕉拢,復(fù)用則顯得更加高效。不過(guò)诚亚,這也意味著組件的生命周期鉤子不會(huì)再被調(diào)用晕换。
復(fù)用組件時(shí),想對(duì)路由參數(shù)的變化作出響應(yīng)的話(huà)站宗,你可以簡(jiǎn)單地 watch(監(jiān)測(cè)變化) $route
對(duì)象:
watch: {
'$route' (to, from) {
// 對(duì)路由變化作出響應(yīng)...
}
}
命名路由的使用
在定義路由的時(shí)候闸准,可以定義一個(gè)name屬性,后續(xù)使用會(huì)很方便
const routes = [
{ name: 'home', path: '/home', component: Home }
]
路由跳轉(zhuǎn)時(shí)梢灭,可以直接使用name屬性
<!-- 聲明式 -->
<router-link :to="{ name: 'home' }">Home</router-link>
// 編程式
this.$router.push({
name: 'home'
})
命名視圖
有時(shí)候想同時(shí)(同級(jí))展示多個(gè)視圖夷家,而不是嵌套展示,例如創(chuàng)建一個(gè)布局敏释,有 sidebar
(側(cè)導(dǎo)航) 和 main
(主內(nèi)容) 兩個(gè)視圖库快,這個(gè)時(shí)候命名視圖就派上用場(chǎng)了。你可以在界面中擁有多個(gè)單獨(dú)命名的視圖钥顽,而不是只有一個(gè)單獨(dú)的出口义屏。如果 router-view
沒(méi)有設(shè)置名字,那么默認(rèn)為 default
耳鸯。
<router-view class="a" name="a"></router-view>
<router-view class="b" name="b"></router-view>
一個(gè)視圖使用一個(gè)組件渲染,因此對(duì)于同個(gè)路由膀曾,多個(gè)視圖就需要多個(gè)組件县爬。確保正確使用 components
配置(帶上 s):
const routes = [
{ path: '/mine', component: Mine, children: [
{ path: '', component: One },
{ path: 'one', components: {
a: One,
b: Two
}},
{ path: 'two', components: {
a: Two,
b: One
} },
]}
]
HTML5 History模式
vue-router
默認(rèn) hash 模式 —— 使用 URL 的 hash 來(lái)模擬一個(gè)完整的 URL,于是當(dāng) URL 改變時(shí)添谊,頁(yè)面不會(huì)重新加載财喳。
如果不想要很丑的 hash,我們可以用路由的 history 模式斩狱,這種模式充分利用 history.pushState
API 來(lái)完成 URL 跳轉(zhuǎn)而無(wú)須重新加載頁(yè)面耳高。
const router = new VueRouter({
mode: 'history',
routes: [...]
})
匹配其它錯(cuò)誤路由
const routes = [
{ path: '*', component: NotFound }
]
導(dǎo)航鉤子
讓我們清楚的知道路由的跳轉(zhuǎn)順序
// 導(dǎo)航鉤子
router.beforeEach((to, from, next) => {
console.log(to); // 要進(jìn)入的路由
console.log(from); // 要離開(kāi)的路由
next()
})
// 路由跳轉(zhuǎn)之后
router.afterEach(router => {
console.log(router)
})
某個(gè)路由獨(dú)享的鉤子
export default {
name: 'mine',
beforeRouteEnter(fo, from, next) {
next(vm => {
// 當(dāng)前組件的實(shí)例
console.log(vm);
})
// 在渲染該組件的對(duì)應(yīng)路由被 confirm 前調(diào)用
// 不!能所踊!獲取組件實(shí)例 `this`
// 因?yàn)楫?dāng)鉤子執(zhí)行前泌枪,組件實(shí)例還沒(méi)被創(chuàng)建
console.log('beforeRouteEnter');
},
beforeRouteUpdate(to, from, next) {
next()
// 在當(dāng)前路由改變,但是該組件被復(fù)用時(shí)調(diào)用
// 舉例來(lái)說(shuō)秕岛,對(duì)于一個(gè)帶有動(dòng)態(tài)參數(shù)的路徑 /foo/:id碌燕,在 /foo/1 和 /foo/2 之間跳轉(zhuǎn)的時(shí)候误证,
// 由于會(huì)渲染同樣的 Foo 組件,因此組件實(shí)例會(huì)被復(fù)用修壕。而這個(gè)鉤子就會(huì)在這個(gè)情況下被調(diào)用愈捅。
// 可以訪(fǎng)問(wèn)組件實(shí)例 `this`
console.log('beforeRouteUpdate');
},
beforeRouteLeave(to, from, next) {
next()
// 導(dǎo)航離開(kāi)該組件的對(duì)應(yīng)路由時(shí)調(diào)用
// 可以訪(fǎng)問(wèn)組件實(shí)例 `this`
console.log('beforeRouteLeave');
}
}
數(shù)據(jù)獲取
導(dǎo)航完成后獲取數(shù)據(jù)
當(dāng)你使用這種方式時(shí),我們會(huì)馬上導(dǎo)航和渲染組件慈鸠,然后在組件的 created
鉤子中獲取數(shù)據(jù)蓝谨。這讓我們有機(jī)會(huì)在數(shù)據(jù)獲取期間展示一個(gè) loading 狀態(tài),還可以在不同視圖間展示不同的 loading 狀態(tài)青团。
<template>
<div id="market">
<div class="loading" v-if="loading">
<h1>Loading</h1>
</div>
<div class="error" v-if="error">
<h1>Error</h1>
</div>
<div class="content" v-if="market">
<h1>market</h1>
<hr>
<list :url="url" category="menu"></list>
</div>
</div>
</template>
<script>
import List from '../components/List'
export default {
name: 'market',
data() {
return {
url: 'http://www.vrserver.applinzi.com/aixianfeng/apihome.php',
loading: false,
error: null,
market: null
}
},
components: { List },
created() {
this.fetchData()
},
methods: {
fetchData() {
this.loading = true
setTimeout(() => {
console.log(this);
this.loading = false
this.market = true
}, 1000);
}
}
}
</script>
<style>
#market h1 {
color: purple;
}
</style>
當(dāng)前tabbar的選中效果
<router-link>
組件支持用戶(hù)在具有路由功能的應(yīng)用中(點(diǎn)擊)導(dǎo)航譬巫。 通過(guò) to
屬性指定目標(biāo)地址,默認(rèn)渲染成帶有正確鏈接的 <a>
標(biāo)簽壶冒,可以通過(guò)配置 tag
屬性生成別的標(biāo)簽.缕题。另外,當(dāng)目標(biāo)路由成功激活時(shí)胖腾,鏈接元素自動(dòng)設(shè)置一個(gè)表示激活的 CSS 類(lèi)名烟零。
只需要在app.vue
中添加樣式即可
<router-link to="/home" tag="li"></router-link>
/* 當(dāng)前被點(diǎn)擊的router-link會(huì)自動(dòng)添加router-link-active類(lèi)名 */
.router-link-active {
background-color: hotpink;
}