react router @4 和 vue路由 詳解(全)

react router @4 和 vue路由

本文大綱:javascript

一、vue路由基礎和使用html

二、react-router @4用法vue

三、什麼是包容性路由?什麼是排他性路由?java

四、react路由有兩個重要的屬性:children和render的區別?react

五、react如何在路由裏面定義一個子路由?vue-router

六、vue如何在路由裏面定義一個子路由?npm

七、react怎麼經過路由傳參?api

八、vue怎麼經過路由傳參?數組

九、怎麼在react裏拿到router對象?瀏覽器

十、怎麼在vue裏拿到router對象?

十一、路由怎麼回退?

十二、react路由守衛?

1三、vue路由守衛?

 


 

一、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、常規使用

     <router-view></router-view>路由匹配到的組件將渲染在這裏
    你能夠把他理解爲一個版塊,好比如今有一個home頁面,分爲兩部分,內容部分和ibar部分,如圖:
    
    這五個頁面共用下面的導航欄,只有導航欄上面的內容不一樣
    <router-view></router-view>就能夠寫在<Ibar></Ibar>的上面
<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

 


 

二、react-router @4用法

  a、大概目錄

       不須要像vue那樣麻煩的用到一個單獨的文件夾,react只須要在index.js中部分配置便可

 


 

  b、準備工做

     yarn add react-router-dom

 

   index.js中

     import { BrowserRouter } from 'react-router-dom'

     

          <BrowserRouter>
            <App />
          </BrowserRouter>
    這樣App內部組件均可以使用
 

 
  c、使用
       一樣是上面那個例子,寫法不同:
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))

 

 


 

 

三、什麼是包容性路由?什麼是排他性路由?

  

  包容性路由:

    若是路由有/food 和 /food/1 那麼在匹配 /food 的時候兩個都能匹配到

    react就是典型的包容性路由

    因此react須要引入Switch標籤,把路由變成排他性的

  

  排他性路由: 

    只要匹配成功一個就不會往下面進行匹配了

    vue是排他性路由

    匹配從上到下,匹配到一個即止

 


 

四、react路由有兩個重要的屬性:children和render,這兩個有什麼區別?

  a、Route 能夠寫行間render,render={()=>{return }}
 
  b、也能夠寫行間children={()={return }}
 
  c、無論匹配與否children都執行
 
  d、render優先級比children高

  


 
五、react如何在路由裏面定義一個子路由?
 
  a、引入在須要子路由的頁面引入Route標籤  
 
   <Route path='/noteDetail/home' component={NodeDe} />

  b、舉個🌰(糖炒栗子,個人愛,爲何我本身作的🌰都那麼難吃???)

 

    

 

    咱們在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子路由

 


 

 

六、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

 


 

七、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" 

 


 

八、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

 


 

 

九、怎麼在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))

 


 

 

十、怎麼在vue裏拿到router對象? 

//在使用的時候

 this.$router.push({ path: '/describe', query: { id: id } }) //接收頁面獲取值
this.$route.query.id

 


 

十一、路由怎麼回退?

  a、vue:this.$router.back(-1)

  b、react:this.props.history.goback()

 


 

 

十二、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

 

1三、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`
  },

  //離開守衛一般用來禁止用戶在還未保存修改前忽然離開。導航該能夠經過來取消
beforeRouteLeave (to, from, next) {
// 導航離開該組件的對應路由時調用 // 能夠訪問組件實例 `this` } }next(false)

  

//beforeRouteEnter守衛不能訪問this, //由於守衛在導航確認前被調用,所以即將登場的新組件還沒被建立。

//不過,能夠你傳經過一個回調給next來訪問組件實例。 //在導航被確認的時候執行回調,而且把組件實例做爲回調方法的參數。
 beforeRouteEnter (to, from, next) { next(vm => { // 經過 `vm` 訪問組件實例
 }) }

完整的導航解析流程

  1. 導航被觸發。
  2. 在失活的組件裏調用離開守衛。
  3. 全局調用的beforeEach守衛。
  4. 在重用的組件裏調用beforeRouteUpdate守衛(2.2+)。
  5. 在路由配置裏調用beforeEnter
  6. 解析異步路由組件。
  7. 在被激活的組件裏調用beforeRouteEnter
  8. 調用全局的beforeResolve守衛(2.5+)。
  9. 導航被確認。
  10. 全局調用的afterEach鉤子。
  11. 觸發DOM更新。
  12. 建立³³用實例好的調用beforeRouteEnter守衛中傳給next的回調函數。

  

  

以上。

原文出處:https://www.cnblogs.com/yangyangxxb/p/10066650.html

相關文章
相關標籤/搜索