react router @4 和 vue路由
本文大綱:
1、vue路由基礎和使用
2、react-router @4用法
3、什么是包容性路由?什么是排他性路由?
4、react路由有兩個重要的屬性:children和render的區別?
5、react如何在路由里面定義一個子路由?
6、vue如何在路由里面定義一個子路由?
7、react怎么通過路由傳參?
8、vue怎么通過路由傳參?
9、怎么在react里拿到router對象?
10、怎么在vue里拿到router對象?
11、路由怎么回退?
12、react路由守衛?
13、vue路由守衛?
1、vue路由基礎和使用
a、大概目錄
我這里建了一個router文件夾,文件夾下有index.html
b、准備工作:
npm install vue-router
或者 yarn add vue-router
c、配置
必須要通過 Vue.use() 明確地安裝路由功能:
在你的文件夾下的 src 文件夾下的 main.js 文件內寫入以下代碼
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter)
附上我的代碼:我是將router的內容寫在了我的router文件夾下的index.html中,然后暴露出去,在main.js中引入
router文件夾下的index.html
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) import Home from 'pages/Home' import Map from 'components/Map' import Home1 from 'components/Home1' import Find from 'components/Find' import Mine from 'components/Mine' import Type from 'components/Type' import Publish from 'components/Publish' import Search from 'components/Search' import Success from 'components/Success' import Need from 'components/Need' import Position0 from 'components/Position' import Like from 'components/scrollX/Like' import S1 from 'components/scrollX/1' import S2 from 'components/scrollX/2' import Listall from 'components/mine/Listall' import Listone from 'components/mine/Listone' import Listchange from 'components/mine/Listchange' const routes = [ { path:'/', redirect:'/ho' }, { path: '/ho', redirect:'/ho/home', component: Home, children: [ { name: 'home', path: 'home', component: Home1, redirect:'/ho/home/like', children :[ { name: 'like', path: 'like', component: Like }, { name: '2000001', path: '2000001', component: S1 }, { name: '2000022', path: '2000022', component: S2 } ] }, { name: 'type', path: 'type', component: Type }, { name: 'need', path: 'need', component: Need }, { name: 'find', path: 'find', component: Find }, { name: 'mine', path: 'mine', component: Mine } ] }, { name: 'search', path: '/search', component: Search }, { name: 'position', path: '/position', component: Position0 }, { name: 'publish', path: '/publish', component: Publish }, { name: 'success', path: '/success', component: Success }, { name: 'listall', path: '/listall', component: Listall }, { name: 'listone', path: '/listone', component: Listone }, { name: 'listchange', path: '/listchange', component: Listchange }, { name: 'map', path: '/map', component: Map } ] const router = new VueRouter({ mode: 'history', routes }) export default router
main.js
import Vue from 'vue' import App from './App.vue' import router from './router' Vue.use(MintUI) Vue.use(ElementUI); Vue.config.productionTip = false new Vue({ router, render: h => h(App) }).$mount('#app')
d、常規使用

<template> <div class="home"> <router-view></router-view> <Ibar></Ibar> </div> </template>
那么在Ibar頁面中如何切換路由呢?
<template>
<div class="ibar">
<router-link to="/ho/home" tag="span" active-class="active">首頁</router-link>
<router-link to="/ho/type" tag="span" active-class="active">類別</router-link>
<router-link to="/ho/need" tag="span" active-class="active">需求</router-link>
<router-link to="/ho/find" tag="span" active-class="active">發現</router-link>
<router-link to="/ho/mine" tag="span" active-class="active">我的</router-link>
</div>
</template>
注意:此處的tag=“span”代表這個按鈕是個span標簽,你可以寫樣式的時候直接寫span標簽的樣式即可
此處的active-class="active"代表點擊哪個按鈕哪個按鈕高亮
此時我們詳細看一下router文件夾下的index.js
//引入vue
import Vue from 'vue'
//引入路由
import VueRouter from 'vue-router'
//把路由掛載到vue上
Vue.use(VueRouter)
//引入我各個路由對應的component組件
import Home from 'pages/Home' import Map from 'components/Map' import Home1 from 'components/Home1' import Find from 'components/Find' import Mine from 'components/Mine' import Type from 'components/Type' import Publish from 'components/Publish' import Search from 'components/Search' import Success from 'components/Success' import Need from 'components/Need' import Position0 from 'components/Position' import Like from 'components/scrollX/Like' import S1 from 'components/scrollX/1' import S2 from 'components/scrollX/2' import Listall from 'components/mine/Listall' import Listone from 'components/mine/Listone' import Listchange from 'components/mine/Listchange'
const routes = [ {
//path是路由的路徑
path:'/',
//redirect代表重定向,因為當前路徑'/'並沒有對應的組件,所以需要重定向到其他路由頁面
redirect:'/ho' }, { path: '/ho', redirect:'/ho/home',
//當不需要重定向的時候,需要component寫上當前路由對應的組件頁面
component: Home,
//有些路由還有子路由,需要用到children[],
//當訪問的時候,<router-link>的屬性to的時候要把所有的父組件都帶上
//如:此處的/ho/home/like
children: [ { name: 'home', path: 'home', component: Home1, redirect:'/ho/home/like', children :[ { name: 'like', path: 'like', component: Like }, { name: '2000001', path: '2000001', component: S1 }, { name: '2000022', path: '2000022', component: S2 } ] }, { name: 'type', path: 'type', component: Type }, { name: 'need', path: 'need', component: Need }, { name: 'find', path: 'find', component: Find }, { name: 'mine', path: 'mine', component: Mine } ] }, { name: 'search', path: '/search', component: Search }, { name: 'position', path: '/position', component: Position0 }, { name: 'publish', path: '/publish', component: Publish }, { name: 'success', path: '/success', component: Success }, { name: 'listall', path: '/listall', component: Listall }, { name: 'listone', path: '/listone', component: Listone }, { name: 'listchange', path: '/listchange', component: Listchange }, { name: 'map', path: '/map', component: Map } ] const router = new VueRouter({
//此處設置mode為history,即不帶#號,在處理數據的時候會更方便一些
mode: 'history',
//ES6的寫法,即routes:routes的簡寫,當key和value名字一樣時,可簡寫
routes })
//把你創建的路由暴露出去,使得main.js可以將其引入並使用
export default router
引申1:
路由有一個meta屬性
可以給該路由掛載一些信息
設置一些自己title、顯示隱藏、左右滑動的方向之類的
meta: { title: "HelloWorld", 要現實的title show: true 設置導航隱藏顯示 }
使用的時候:this.$route.meta.show
<Bottom v-show=
"this.$route.meta.show"
></Bottom>
引申2:
動態路由
{ path:"/two/:id", component:Two, }
獲取數據this.$route.params.動態路由的名字
此處是:this.$route.params.id
引申3:
路由別名alias
{ path: '/a', component: A, alias: '/b' }
// /a 的別名是 /b
//意味着,當用戶訪問 /b 時,URL 會保持為 /b,但是路由匹配則為 /a
//就像用戶訪問 /a 一樣
//簡單的說就是給 /a 起了一個外號叫做 /b ,但是本質上還是 /a
2、react-router @4用法
a、大概目錄
不需要像vue那樣麻煩的用到一個單獨的文件夾,react只需要在index.js中部分配置即可
b、准備工作
yarn add react-router-dom
index.js中
import { BrowserRouter } from 'react-router-dom'
import React, { Component } from 'react'; import {Bar} from 'components/common/ibar' import ShopDetail from 'pages/shopDetail/shopDetail' import NodeDe from 'pages/noteDetail/NodeDe' import Car from 'pages/car/Car' import Admin from 'pages/admin/Admin' import Admin1 from 'pages/admin/Admin1' import GoodDetail from 'pages/goodDetail/goodDetail' import { Route, Switch, Redirect } from 'react-router-dom' class App extends Component { render() { return (
//這里為什么要用Switch包裹呢?
//<Switch>是唯一的因為它僅僅只會渲染一個路徑
<Switch>
//Redirect代表重定向,如果加了exact代表精准匹配
<Redirect exact from="/" to="/home"></Redirect> <Route path='/home' component={Bar}/> <Route path="/shopDetail/:shopId/:shopName/:shopNote/:shopPic" component={ShopDetail} /> <Route path='/noteDetail/:noteId' component={NodeDe} /> <Route path='/goodDetail/:goodId/:shopId' component={GoodDetail} /> <Route path='/car' component={Car} /> <Route path='/admin' component={Admin}/> <Route path='/admin1/:phone' component={Admin1}/> </Switch> ); } } export default App;
當點擊哪里需要跳轉的時候,在標簽外面包一個<Link to= ' 路由路徑 ' ></Link>
動態路由/xxx/:xx,如上圖
引申1:HashRouter和BrowserRouter
它們兩個是路由的基本,就像蓋房子必須有地基一樣
我們需要將它們包裹在最外層,我們只要選擇其一就可以了。
現在講它們的不同:
HashRouter
如果你使用過react-router2或3或者vue-router
你經常會發現一個現象就是url中會有個#,
例如localhost:3000/#
HashRouter就會出現這種情況,它是通過hash值來對路由進行控制
如果你使用HashRouter,你的路由就會默認有這個#。
BrowserRouter
很多情況下我們則不是這種情況,我們不需要這個#
因為它看起來很怪,這時我們就需要用到BrowserRouter。
引申2:Link和NavLink的選擇
兩者都是可以控制路由跳轉的,不同點是NavLink的api更多,更加滿足你的需求。
Link:主要api是to,to可以接受string或者一個object,來控制url
NavLink:它可以為當前選中的路由設置類名、樣式以及回調函數等。
引申3:withRouter高階組件
//引入withRouter
import {
Link,
withRouter
} from 'react-router-dom'
//代碼結尾暴露的時候,把要暴露的組件包裹在withRouter中,做成一個高階組件,
//將react-router 的 history,location,match 三個對象傳入
//將組件包一層withRouter,就可以拿到需要的路由信息
//獲取路由信息的時候this.props.location
withRouter(GoodDetail)
withRouter(connect(mapState, mapDispatch)(GoodDetail))
3、什么是包容性路由?什么是排他性路由?
包容性路由:
如果路由有/food 和 /food/1 那么在匹配 /food 的時候兩個都能匹配到
react就是典型的包容性路由
所以react需要引入Switch標簽,把路由變成排他性的
排他性路由:
只要匹配成功一個就不會往下面進行匹配了
vue是排他性路由
匹配從上到下,匹配到一個即止
4、react路由有兩個重要的屬性:children和render,這兩個有什么區別?
a、Route 可以寫行間render,render={()=>{return }}
<Route path='/noteDetail/home' component={NodeDe} />


我們在home頁面里(左邊一溜的父組件)該點擊的地方
export const Home = () => (
<ul>
<li>
<NavLink to='/home' exact activeStyle ={selectedStyle}>首頁</NavLink>
</li>
<li>
<NavLink to='/about' activeStyle ={selectedStyle}>關於我們</NavLink>
</li>
<li>
<NavLink to='/event' activeStyle ={selectedStyle}>企業事件</NavLink>
</li>
<li>
<NavLink to='/product' activeStyle ={selectedStyle}>公司產品</NavLink>
</li>
<li>
<NavLink to='/us' activeStyle ={selectedStyle}>聯系我們</NavLink>
</li>
</ul>
)
我們在home頁面里(左邊一溜的父組件)設置內容應該不同的地方
<Redirect exact from="/" to="/home"></Redirect> <Route path='/home' exact component={Home}/> <Route path='/about' component={About}/> <Route path='/event' component={Event}/> <Route path='/product' component={Product}/> <Route path='/us' component={Us}/>
我們在關於我們頁面該點擊的地方
export const AboutMenu = () => (
<ul className="about-menu">
<li>
<NavLink to='/about' exact activeStyle ={selectedStyle}>公司簡介</NavLink>
</li>
<li>
<NavLink to='/about/history' activeStyle ={selectedStyle}>公司歷史</NavLink>
</li>
<li>
<NavLink to='/about/services' activeStyle ={selectedStyle}>公司服務</NavLink>
</li>
<li>
<NavLink to='/about/location' activeStyle ={selectedStyle}>企業位置</NavLink>
</li>
</ul>
)
我們在關於我們頁面該實現內容不同的地方
<Route path='/about' exact component={Company}/> <Route path='/about/history' component={History}/> <Route path='/about/services' component={Services}/> <Route path='/about/location' component={Location}/>
由此便實現了react子路由
6、vue如何在路由里面定義一個子路由?
給父路由加一個 children:[]
參考我的<1.d>的代碼
const routes = [ { //path是路由的路徑 path:'/', //redirect代表重定向,因為當前路徑'/'並沒有對應的組件,所以需要重定向到其他路由頁面 redirect:'/ho' }, { path: '/ho', redirect:'/ho/home', //當不需要重定向的時候,需要component寫上當前路由對應的組件頁面 component: Home, //有些路由還有子路由,需要用到children[], //當訪問的時候,<router-link>的屬性to的時候要把所有的父組件都帶上 //如:此處的/ho/home/like children: [
//子路由寫在children數組里,仍舊以對象的形式
{ name: 'home', path: 'home', component: Home1, redirect:'/ho/home/like', children :[ { name: 'like', path: 'like', component: Like }, { name: '2000001', path: '2000001', component: S1 }, { name: '2000022', path: '2000022', component: S2 } ] }, { name: 'type', path: 'type', component: Type }, { name: 'need', path: 'need', component: Need }, { name: 'find', path: 'find', component: Find }, { name: 'mine', path: 'mine', component: Mine } ] }, { name: 'search', path: '/search', component: Search }, { name: 'position', path: '/position', component: Position0 }, { name: 'publish', path: '/publish', component: Publish }, { name: 'success', path: '/success', component: Success }, { name: 'listall', path: '/listall', component: Listall }, { name: 'listone', path: '/listone', component: Listone }, { name: 'listchange', path: '/listchange', component: Listchange }, { name: 'map', path: '/map', component: Map } ] const router = new VueRouter({ //此處設置mode為history,即不帶#號,在處理數據的時候會更方便一些 mode: 'history', //ES6的寫法,即routes:routes的簡寫,當key和value名字一樣時,可簡寫 routes }) //把你創建的路由暴露出去,使得main.js可以將其引入並使用 export default router
7、react怎么通過路由傳參?
a、通配符傳參(刷新頁面數據不丟失)
//在定義路由的時候 <Route path='/path/:自己起個名字' component={Path}/> //在路由點擊跳轉的時候 <Link to="/path/你要傳的參數">通配符</Link> //另一個頁面接收傳來的參數 this.props.match.params.你起的名字
舉個🌰
另一個頁面接收值的時候:
this.props.match.params.id
b、query傳參(刷新頁面數據丟失)
//路由定義 <Route path='/query' component={Query}/> //跳轉的時候 var query = { pathname: '/query', query: '我是通過query傳值 ' } <Link to={query}>query</Link> //另一個頁面使用的時候 this.props.location.query 這里的this.props.location.query === '我是通過query傳值'
c、state傳參(刷新頁面數據丟失,同query差不多,只是屬性不一樣,而且state傳的參數是加密的,query傳的參數是公開的)
//Route定義 <Link to={state}>state</Link> //使用的時候 var state = { pathname: '/state', state: '我是通過state傳值' } <Route path='/state' component={State}/> //另一個頁面獲取值的時候 this.props.location.state 這里的this.props.location.state === '我是通過query傳值'
d、路由?傳參數
此處的foodmenu通過路由?后面傳參數
在另一個頁面的this.props.location.search可以獲取到 "?id=6"
8、vue怎么通過路由傳參?
a、通配符傳參數
//在定義路由的時候 { path: '/describe/:id', name: 'Describe', component: Describe } //在使用的時候 this.$router.push({ path: `/describe/${id}`, }) //接收頁面獲取值 this.$route.params.id
b、params傳參,跳轉的時候不會顯示在url上
//在定義路由的時候 { path: '/describe', name: 'Describe', component: Describe } //在使用的時候 this.$router.push({ name: 'Describe', params: { id: id } }) //接收頁面獲取值 this.$route.params.id
c、query傳參,傳餐的時候在url顯示? key=value & key=value
//在定義路由的時候 { path: '/describe', name: 'Describe', component: Describe } //在使用的時候 this.$router.push({ path: '/describe', query: { id: id } }) //接收頁面獲取值 this.$route.query.id
9、怎么在react里拿到router對象?
import withRouter 並且 export組件的時候,用withRouter把組件包起來
//引入withRouter import { Link, withRouter } from 'react-router-dom' //代碼結尾暴露的時候,把要暴露的組件包裹在withRouter中,做成一個高階組件, //將react-router 的 history,location,match 三個對象傳入 //將組件包一層withRouter,就可以拿到需要的路由信息 //獲取路由信息的時候this.props.location withRouter(GoodDetail) withRouter(connect(mapState, mapDispatch)(GoodDetail))
10、怎么在vue里拿到router對象?
//在使用的時候 this.$router.push({ path: '/describe', query: { id: id } }) //接收頁面獲取值 this.$route.query.id
11、路由怎么回退?
a、vue:this.$router.back(-1)
b、react:this.props.history.goback()
12、react路由守衛?
a、在之前的版本中,React Router 也提供了類似的 onEnter
鈎子,但在 React Router 4.0 版本中,取消了這個方法。
b、那么在react中如果我們也需要路由守衛怎么辦?比如在跳轉路由前需要判斷用戶是否登錄?如果登錄才可以進行跳轉,否則沒有權限
c、
//下面是我的實現方式, //首先,准備一份路由表, //包含了路由的地址,組件以及是否需要權限校驗: import { HomePage } from '../pages/home/home.page'; import { LoginPage } from '../pages/login/login.page'; import { ErrorPage } from '../pages/error/error.page'; interface routerConfigModel { path:string, component?:any, auth?:boolean } export const routerConfig:routerConfigModel[] = [ { path:'/', component:HomePage, auth:true, }, { path:'/home', component:HomePage, auth:true, }, { path:'/login', component:LoginPage, }, { path:'/404', component:ErrorPage } ]; //將 auth 設置為 true,表示該路由需要權限校驗。 //然后,定義 Router 組件,該組件是經過高階組件包裝后的結果: import * as React from 'react'; import { HashRouter,Switch } from 'react-router-dom'; import { FrontendAuth } from '../components/frontend-auth/frontend-auth.component' import { routerConfig } from './router.config' export class Router extends React.Component{ render(){ return( <HashRouter> <Switch> <FrontendAuth config={routerConfig} /> </Switch> </HashRouter> ); } } //所有的路由跳轉,都交給 FrontendAuth 高階組件代理完成。 //下面是 FrontendAuth 組件的實現: import * as React from 'react'; import { Route,Redirect } from 'react-router-dom'; import { propsModel } from './frontend-auth.model' export class FrontendAuth extends React.Component<any,propsModel>{ render(){ const { location,config } = this.props; const { pathname } = location; const isLogin = localStorage.getItem('__config_center_token') // 如果該路由不用進行權限校驗,登錄狀態下登陸頁除外 // 因為登陸后,無法跳轉到登陸頁 // 這部分代碼,是為了在非登陸狀態下,訪問不需要權限校驗的路由 const targetRouterConfig = config.find((v:any) => v.path === pathname); if(targetRouterConfig && !targetRouterConfig.auth && !isLogin){ const { component } = targetRouterConfig; return <Route exact path={pathname} component={component} /> } if(isLogin){ // 如果是登陸狀態,想要跳轉到登陸,重定向到主頁 if(pathname === '/login'){ return <Redirect to='/' /> }else{ // 如果路由合法,就跳轉到相應的路由 if(targetRouterConfig){ return <Route path={pathname} component={targetRouterConfig.component} /> }else{ // 如果路由不合法,重定向到 404 頁面 return <Redirect to='/404' /> } } }else{ // 非登陸狀態下,當路由合法時且需要權限校驗時,跳轉到登陸頁面,要求登陸 if(targetRouterConfig && targetRouterConfig.auth){ return <Redirect to='/login' /> }else{ // 非登陸狀態下,路由不合法時,重定向至 404 return <Redirect to='/404' /> } } } } //以及對應的 Model: export interface propsModel { config:any[], } //頁面上的路由跳轉,都由 FrontendAuth 高階組件代理了, //在 Switch 組件內部,不再是 Route 組件, //而只有一個 FrontendAuth 組件。 //FrontendAuth 組件接收一個名為 config 的 Props,這是一份路由表。 //同時,由於 FrontendAuth 組件放在了 Switch 組件內部,React Router 還自動為 FrontendAuth 注入了 location 屬性, //當地址欄的路由發生變化時,就會觸發 location 屬性對象上的 pathname 屬性發生變化, //從而觸發 FrontendAuth 的更新(調用 render 函數)。 //FrontendAuth 的 render 函數中, //根據 pathname 查找到路由表中的相關配置, //如果該配置中指定了無需校驗,就直接返回相應的 Route 組件。 //如果查找到的配置需要進行校驗,再根據是否登陸進行處理,具體可以查看代碼中的注釋。 總結一下,實現路由守衛需要考慮到以下的問題: 未登錄情況下,訪問不需要權限校驗的合法頁面:允許訪問 登陸情況下,訪問登陸頁面:禁止訪問,跳轉至主頁 登陸情況下,訪問除登陸頁以外的合法頁面:允許訪問 登陸情況下,訪問所有的非法頁面:禁止訪問,跳轉至 404 未登錄情況下,訪問需要權限校驗的頁面:禁止訪問,跳轉至登陸頁 未登錄情況下,訪問所有的非法頁面:禁止訪問,跳轉至 404
13、vue路由守衛
a、beforeEach
全局守衛
(每個路由調用前都會觸發,根據from和to來判斷是哪個路由觸發)
const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => { // ... }) //每個守衛功能都有三個參數: //to: Route:導航到的目標Route對象 //from: Route:當前路線被導航離開 //next: Function:必須調用此函數來解析鈎子 // next():繼續前進到管道中的下一個鈎子。如果沒有留下掛鈎,則確認導航。 // next(false):中止當前導航。如果瀏覽器URL已更改(由用戶手動或通過后退按鈕),則會將其重置為from路徑的URL 。 // next('/')或next({ path: '/' }):重定向到其他位置。當前導航將中止,並將啟動一個新導航。你可以通過任何位置對象next,它允許您指定類似的選項replace: true,name: 'home'在使用任何選項router-link的to道具或router.push // next(error):(2.4.0+)如果傳遞給的參數next是一個實例Error,導航將被中止,錯誤將傳遞給通過注冊的回調router.onError()。 `
舉個🌰
import Vue from 'vue'; import Router from 'vue-router'; import LoginPage from '@/pages/login'; import HomePage from '@/pages/home'; import GoodsListPage from '@/pages/good-list'; import GoodsDetailPage from '@/pages/good-detail'; import CartPage from '@/pages/cart'; import ProfilePage from '@/pages/profile'; Vue.use(Router) const router = new Router({ routes: [ { path: '/', // 默認進入路由 redirect: '/home' //重定向 }, { path: '/login', name: 'login', component: LoginPage }, { path: '/home', name: 'home', component: HomePage }, { path: '/good-list', name: 'good-list', component: GoodsListPage }, { path: '/good-detail', name: 'good-detail', component: GoodsDetailPage }, { path: '/cart', name: 'cart', component: CartPage }, { path: '/profile', name: 'profile', component: ProfilePage }, { path: '**', // 錯誤路由 redirect: '/home' //重定向 }, ] }); // 全局路由守衛 router.beforeEach((to, from, next) => { console.log('navigation-guards'); // to: Route: 即將要進入的目標 路由對象 // from: Route: 當前導航正要離開的路由 // next: Function: 一定要調用該方法來 resolve 這個鈎子。執行效果依賴 next 方法的調用參數。 const nextRoute = ['home', 'good-list', 'good-detail', 'cart', 'profile']; let isLogin = global.isLogin; // 是否登錄 // 未登錄狀態;當路由到nextRoute指定頁時,跳轉至login if (nextRoute.indexOf(to.name) >= 0) { if (!isLogin) { console.log('what fuck'); router.push({ name: 'login' }) } } // 已登錄狀態;當路由到login時,跳轉至home if (to.name === 'login') { if (isLogin) { router.push({ name: 'home' }); } } next(); }); export default router;
b、beforeResolve(2.5.0新增)
全局解析守衛
和router.beforeEach
類似,區別是在導航被確認之前,同時在所有組件內守衛和異步路由組件被解析之后,解析守衛就被調用
c、afterEach
全局后置鈎子
router.afterEach((to, from) => { // ... }) //不會接受next函數也 //也不會改變導航本身
d、beforeEnter
路由獨享的守衛
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // ... } } ] }) //與全局前置守衛的方法參數是一樣的
e、
組件內的守衛
beforeRouteEnter
beforeRouteUpdate
(2.2新增)beforeRouteLeave
const Foo = { template: `...`, beforeRouteEnter (to, from, next) { // 在渲染該組件的對應路由被 confirm 前調用 // 不!能!獲取組件實例 `this` // 因為當守衛執行前,組件實例還沒被創建 }, beforeRouteUpdate (to, from, next) { // 在當前路由改變,但是該組件被復用時調用 // 舉例來說,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候, // 由於會渲染同樣的 Foo 組件,因此組件實例會被復用。而這個鈎子就會在這個情況下被調用。 // 可以訪問組件實例 `this` },
//離開守衛通常用來禁止用戶在還未保存修改前突然離開。導航該可以通過next(false)
來取消
beforeRouteLeave (to, from, next) { // 導航離開該組件的對應路由時調用 // 可以訪問組件實例 `this` } }
//beforeRouteEnter守衛不能訪問this, //因為守衛在導航確認前被調用,因此即將登場的新組件還沒被創建。 //不過,可以你傳通過一個回調給next來訪問組件實例。 //在導航被確認的時候執行回調,並且把組件實例作為回調方法的參數。 beforeRouteEnter (to, from, next) { next(vm => { // 通過 `vm` 訪問組件實例 }) }
完整的導航解析流程
- 導航被觸發。
- 在失活的組件里調用離開守衛。
- 全局調用的
beforeEach
守衛。 - 在重用的組件里調用
beforeRouteUpdate
守衛(2.2+)。 - 在路由配置里調用
beforeEnter
。 - 解析異步路由組件。
- 在被激活的組件里調用
beforeRouteEnter
。 - 調用全局的
beforeResolve
守衛(2.5+)。 - 導航被確認。
- 全局調用的
afterEach
鈎子。 - 觸發DOM更新。
- 創建³³用實例好的調用
beforeRouteEnter
守衛中傳給next
的回調函數。
以上。