vue-----路由
使用vue-cli安裝不需要另外安裝路由贯被,只需要在安裝時候選擇Manually select features,然后選到router按下空格就行**
- vue路由分為前端路由和后端路由
路由配置
Router
Views
import router from "./router"
new Vue({
router,
render: h => h(App)
}).$mount('#app')```
初始化路由
在路由模塊的入口文件index.js配合router
```//引入vue
import Vue from 'vue';
//引入router
import VueRouter from 'vue-router'
//引入組件
import Home from "../xxx/Home.vue";
import About from "../xxx/About.vue"
?
//全局配置路由
Vue.use(VueRouter)
?
//集成路由
const routes = [
{
//路徑
path:"/",
//路由名稱
name:"home",
//路由加載的組件
component:Home
},
{
path:"/about",
name:"about",
component:About,
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
?
export default router```
#### 嵌套路由
嵌套路由用到了children屬性咳胃,實現(xiàn)嵌套
```//引入vue
import Vue from 'vue';
//引入router
import VueRouter from 'vue-router'
//引入組件
import Home from "../xxx/Home.vue";
import Hot from "../views/Hot.vue";
?
//全局配置路由
Vue.use(VueRouter)
?
//集成路由
const routes = [
{
//路徑
path:"/",
//路由名稱
name:"home",
//路由加載的組件
component:Home,
//嵌套路由
children:[
{
path: "/hot",
name: "hot",
component: Hot
}
]
},
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
?
export default router```
路由管理下的組件都會加載到一個router-view標簽中植康,在app.vue中有一個最大的router-view標簽管理所有組件
```<template>
<div>
<!-- app.vue -->
<!-- 路由管理下的組件都加載router-view里面 -->
<router-view/>
</divvue
</template>```
home.vue
```<template>
<div>
<button @click="onClick">點擊跳轉(zhuǎn)</button>
<!-- 如果home頁面有嵌套路由 也會加載在router-view里面 -->
<router-view/>
</div>
</template>
?
<script>
export default{
methods:{
onClick(){
//點擊跳轉(zhuǎn)嵌套路由
this.$router.push("/hot")
}
}
}
</script>```
#### 編程式導航
* 在vue實力內(nèi)部,你可以通過$router訪問路由實例展懈,因此你可以調(diào)用this.$router.push跳轉(zhuǎn)销睁,這個方法會向 history 棧添加一個新的記錄,所以存崖,當用戶點擊瀏覽器后退按鈕時榄攀,則回到之前的 URL。
* this.$router.push有兩種跳轉(zhuǎn)方式金句,一個是path+query檩赢,另一個是name+params
**path+query**
```this.$router.push({
path:'/hello',
query:{
name:'word',
age:'11'
}
})```
**name+params**
```this.$router.push({
name:'hello',
params:{
name:'word',
age:'11'
}
})```
一般推薦使用path+query進行路由傳參
* 使用params帶參數(shù),需要對應使用name來指明路徑违寞,query帶參數(shù)贞瞒,則path,name都可以
* .params帶參數(shù)跳轉(zhuǎn),在跳轉(zhuǎn)后頁面再進行跳轉(zhuǎn)或刷新都有可能導致數(shù)據(jù)丟失趁曼,建議使用query帶參數(shù)
* query相當于get請求军浆,頁面跳轉(zhuǎn)的時候,可以在地址欄看到請求參數(shù)挡闰,而params相當于post請求乒融,參數(shù)不會再地址欄中顯示
* params是路由的一部分,必須要有掰盘。query是拼接在url后面的參數(shù),沒有也沒關(guān)系
* params一旦設(shè)置在路由赞季,params就是路由的一部分,如果這個路由有params傳參申钩,但是在跳轉(zhuǎn)的時候沒有傳遞這個參數(shù)次绘,會導致跳轉(zhuǎn)失敗或者頁面沒有內(nèi)容邮偎,比如跳轉(zhuǎn)router1/:id
```<router-link :to="{name:'router1',params:{id:staus}}">正確</router-link>
<router-link :to="{name:'router1',params:{id2:staus}}">錯誤</router-link>```
#### 命名視圖
有時候想同時 (同級) 展示多個視圖,而不是嵌套展示义黎,例如創(chuàng)建一個布局,有 `sidebar` (側(cè)導航) 和 `main` (主內(nèi)容) 兩個視圖廉涕,這個時候命名視圖就派上用場了。你可以在界面中擁有多個單獨命名的視圖火的,而不是只有一個單獨的出口。如果 `router-view` 沒有設(shè)置名字馏鹤,那么默認為 `default`。
```<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>
一個視圖使用一個組件渲染湃累,因此對于同個路由,多個視圖就需要多個組件治力。確保正確使用 components配置 (帶上 s):
routes: [
{
path: '/',
components: {
default: Foo,
a: Bar,
b: Baz
}
}
]
})
在這個默認路由下面,
第一個非未命名視圖顯示Foo組件
第二個name名為a的視圖顯示Bar組件
name名為b的視圖顯示Baz組件
下面這個是一個示例
<div class="hello">
<ul class="nav">
<li><router-link to="/list1">list1</router-link></li>
<li><router-link to="/list2">list2</router-link></li>
<li><router-link to="/list3">list3</router-link></li>
</ul>
<h6>默認視圖</h6>
<div class="view">
<router-view></router-view>
</div>
<h6>a視圖</h6>
<div class="view">
<router-view name="a"></router-view>
</div>
<h6>b視圖</h6>
<div class="view">
<router-view name="b"></router-view>
</div>
</div>
</template>
router配置:
{
path: '/',
name: 'HelloWorld',
component: HelloWorld,
children:[
{
path:'',
components:{
default:List1,
a:List2,
b:List3
}
},
{
path:'list1',
components:{
default:List1,
a:List2,
b:List3
}
},
{
path:'list2',
components:{
default:List2,
a:List1,
b:List3
}
},
{
path:'list3',
components:{
default:List3,
a:List1,
b:List2
}
}
]
}
]
嵌套命名視圖
我們也有可能使用命名視圖創(chuàng)建嵌套視圖的復雜布局宵统。這時你也需要命名用到的嵌套 router-view
組件
path: '/',
// 你也可以在頂級路由就配置命名視圖
component: name,
//嵌套路由
children: [{
path: '/emails',
component: UserEmailsSubscriptions
},
{
path: 'profile',
//命名視圖
components: {
default: UserProfile,
helper: UserProfilePreview
}
}]
}
重定向
重定向也是通過 routes
配置來完成,下面例子是從 /a
重定向到 /b
:
routes: [
{ path: '/a', redirect: '/b' }
]
})
const router = new VueRouter({
routes: [
{ path: '/a', redirect: { name: 'foo' }}
]
const router = new VueRouter({
routes: [
{ path: '/a', redirect: to => {
// 方法接收 目標路由 作為參數(shù)
// return 重定向的 字符串路徑/路徑對象
}}
]
})
代碼示例:
redirect: to => {
const { hash, params, query } = to
if (query.to === 'foo') {
return { path: '/foo', query: null }
}
if (hash === '#baz') {
return { name: 'baz', hash: '' }
}
if (params.id) {
return '/with-params/:id'
} else {
return '/bar'
}
}
}
導航守衛(wèi)
vue-router
提供的導航守衛(wèi)主要用來通過跳轉(zhuǎn)或取消的方式守衛(wèi)導航瓢省。有多種機會植入路由導航過程中:全局的, 單個路由獨享的, 或者組件級的。
全局前置守衛(wèi)beforeEach
當一個導航觸發(fā)時痊班,全局前置守衛(wèi)按照創(chuàng)建順序調(diào)用勤婚。守衛(wèi)是異步解析執(zhí)行,此時導航在所有守衛(wèi) resolve 完之
前一直處于 等待中涤伐。
你可以使用 router.beforeEach
注冊一個全局前置守衛(wèi):
let loginStatus = false
const router = [
{
path: '/',
name: 'Home',
component: Home,
//設(shè)置meta前往路由是否需要通過守衛(wèi)
meta: {
isLogin: false
}
},
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue'),
meta: {
isLogin: false
}
},
{
path: "/mine",
name: "mine",
component: () => import("../views/Mine.vue"),
meta: {
isLogin: true
}
}
]
// 參數(shù)分別是 即將進入的頁面 正要離開的路由 一定要調(diào)用next才能生效
router.beforeEach((to, from, next) => {
// 如果要進入的頁面需要登錄
if (to.meta.isLogin === true) {
// 如果登錄狀態(tài)為未登錄
if (loginStatus === false) {
// 則去登錄
next("/login")
} else {
// 否則直接跳轉(zhuǎn)
next()
}
} else {
next()
}
})
路由獨享守衛(wèi)beforeEnter
const routes = [
{
path: "/shoppinglist",
name: "shoppinglist",
component: ShoppingList,
// 設(shè)置路由獨享守衛(wèi)
beforeEnter: (to, from, next) => {
// 判斷登錄狀態(tài)
if (loginStatus === false) {
next("/login")
} else {
next()
}
}
}
]
組件內(nèi)守衛(wèi)beforeRouteLeave
export default {
// 設(shè)置組件內(nèi)守衛(wèi)beforeRouteLeave
beforeRouteLeave (to, from, next) {
window.console.log(to)
window.console.log(from)
window.alert("真的要離開嗎")
next()
}
}
</script>
每個守衛(wèi)方法接收三個參數(shù):
to: Route: 即將要進入的目標 路由對象
from: Route: 當前導航正要離開的路由
-
next: Function: 一定要調(diào)用該方法來 resolve 這個鉤子馒胆。執(zhí)行效果依賴
next
方法的調(diào)用參數(shù)缨称。next(): 進行管道中的下一個鉤子。如果全部鉤子執(zhí)行完了祝迂,則導航的狀態(tài)就是 confirmed (確認的)睦尽。
next(false): 中斷當前的導航。如果瀏覽器的 URL 改變了 (可能是用戶手動或者瀏覽器后退按鈕)液兽,那么 URL 地址會重置到
from
路由對應的地址。next('/') 或者 next({ path: '/' }): 跳轉(zhuǎn)到一個不同的地址掌动。當前的導航被中斷四啰,然后進行一個新的導航。你可以向
next
傳遞任意位置對象粗恢,且允許設(shè)置諸如replace: true
柑晒、name: 'home'
之類的選項以及任何用在router-link
的to
prop 或router.push
中的選項。next(error): (2.4.0+) 如果傳入
next
的參數(shù)是一個Error
實例眷射,則導航會被終止且該錯誤會被傳遞給router.onError()
注冊過的回調(diào)匙赞。
確保要調(diào)用 next 方法,否則鉤子就不會被 resolved妖碉。