vue-router與react-router全面對比


一、包容性路由與排他性路由

1、包容性路由。多個<Route> 可以同時進行匹配和渲染,例如:如果路由有/food 和 /food/1 那么在匹配 /food 的時候兩個都能匹配到。而react-router v4以后的版本就是以包容性路由為基礎。例如:如果路由有/food 和 /food/1 那么在匹配 /food 的時候兩個都能匹配到。

2、排他性路由。屬於自上向下的匹配方式,只要匹配成功一個,就不會再繼續向下匹配。vue的路由實現方式就屬於是排他性路由。

二、vue-router與react-router的基礎用法

vue-router與react-router在使用方式上雖然有較大差異,但是其實提供的功能是大同小異的,下面我們來詳細的對比下看看。

1、引入方式

a.vue必須要通過 Vue.use() 明確地安裝路由功能;也可以將Vue.use()和vue-router的引入都放在獨立模塊中,(比如:router/index.js中,再在main.js中引入router/index.js)。

b.react只需要在index.js中直接進行部分配置即可使用。

2、router的基礎組件

a.vue-router的常用組件主要是keep-alive、router-link和router-view。

  • router-link 定義點擊后導航到哪個路徑下;對應的組件內容渲染到router-view中。
  • 被keep-alive包裹住的組件,會被vue進行緩存。當組件在keep-alive內被切換時組件的activated、deactivated這兩個生命周期鈎子函數會被執行,不會再執行掛載和銷毀組件的生命周期函數。同時也可以使用keep-alive組件身上的include和excludes兩個屬性來區分哪些組件需要被緩存,那些不需要。

b.react-router的常用組件主要是<switch />、<Route />和<CacheRoute />。

  • switch組件用來將react的包容性路由轉換為排他性路由,每次只要匹配成功就不會繼續向下匹配。
  • Route組件定義了URL路徑與組件的對應關系。

  • CacheRoute組件的作用與Route大致相同,使用 CacheRoute 的組件將會得到一個名為 cacheLifecycles 的屬性,里面包含兩個額外生命周期的注入函數 didCache 和 didRecover,分別用在組件 被緩存 和 被恢復 時觸發。類比於vue-router中keep-alive實現的效果。

3、路由的配置

a.vue-router路由的屬性配置。

  • path:匹配組件的路由。
  • component:匹配到以后要渲染的組件。
  • name:路由的名稱。
  • children:該路由下的子路由。
  • meta:可以利用meta屬性在路由下掛載一些自定義的信息,比如對路由的權限配置。
  • redirect和alias:alias相當於是給路由添加了一個別名,頁面上的路由會展示為path,但是同時也可以使用alias設置的別名來訪問;redirect則會將頁面從path的路徑重定向到redirect設置的路徑。
  • 另外,vue-router可以配置動態路由例如下面這種形式,可以在組件內通過this.$route.params.id獲取url中的內容
    { path:"/two/:id", component:Two, }

     

  • vue-router的大概目錄

b.react-router的路由配置。

不同於vue-router的使用對象來配置路由,react-router配置路由的方式可以使用Object,也可以使用jsx進行路由的配置。

  • path、component的用途與vue-router的相同。
  • exact:Boolean 標記着是否是開啟排他性路由。
  • from和to:對應着vue-router中的path和redirect兩個屬性,可以將路由從from從定向到to匹配的組件。
  • Link和NavLink:兩者都是用來做類似於router-link的跳轉,但是不同的是NavLink可以為當前選中的路由設置類名、樣式以及回調函數等。
  • react-router的動態路由的用法和vue-router的用法一致。
  • react-router的大概目錄

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

4、路由模式

a.vue-router主要分為hash和history兩種模式

  • hash —— 即地址欄 URL 中的 # 符號(此 hash 不是密碼學里的散列運算)。比如這個 URL:http://www.abc.com/#/hello hash 的值為 #/hello。它的特點在於:hash 雖然出現在 URL 中,但不會被包括在 HTTP 請求中,對后端完全沒有影響,因此改變 hash 不會重新加載頁面。
  • history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定瀏覽器支持)這兩個方法應用於瀏覽器的歷史記錄棧,在當前已有的 back、forward、go 的基礎之上,它們提供了對歷史記錄進行修改的功能。只是當它們執行修改時,雖然改變了當前的 URL,但瀏覽器不會立即向后端發送請求。
  • 因此可以說,hash 模式和 history 模式都屬於瀏覽器自身的特性,Vue-Router 只是利用了這兩個特性(通過調用瀏覽器提供的接口)來實現前端路由.

b.react-router是建立在history之上的,常用的history有browserHistory、hashHistory和createMemoryHistory三種模式

  • browserHistory —— Browser history 是使用 React Router 的應用推薦的 history。它使用瀏覽器中的 History API 用於處理 URL,創建一個像example.com/some/path這樣真實的 URL 。服務器需要做好處理 URL 的准備。處理應用啟動最初的 / 這樣的請求應該沒問題,但當用戶來回跳轉並在 /accounts/123 刷新時,服務器就會收到來自 /accounts/123 的請求,這時你需要處理這個 URL 並在響應中包含 JavaScript 應用代碼。
  • hashHistory —— 使用 URL 中的 hash(#)部分去創建形如 example.com/#/some/path 的路由。
  • createMemoryHistory —— Memory history 不會在地址欄被操作或讀取。這就解釋了我們是如何實現服務器渲染的。同時它也非常適合測試和其他的渲染環境(像 React Native );
和另外兩種history的一點不同是你必須創建它,這種方式便於測試。

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

  a.Route 可以寫行間render,render={()=>{return }}

  b.也可以寫行間children={()={return }}

  c.不管匹配與否children都執行

  d.render優先級比children高

6、通過路由傳遞參數

a.react的路由參數傳遞

  • 通配符傳參(刷新頁面數據不丟失)

//在定義路由的時候

<Route path='/path/:自己起個名字' component={Path}/>


//在路由點擊跳轉的時候

<Link to="/path/你要傳的參數">通配符</Link>


//另一個頁面接收傳來的參數

this.props.match.params.你起的名字

 

  • 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傳值'

     

  • 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傳值'

     

  • 直接通過url拼接傳參

    // 跳轉方式this.props.history.push(`/child02?${a=1}`) // 獲取參數this.props.location.search // "?a=1"



b.vue的路由參數傳遞

  • 通配符傳參

//在定義路由的時候

{
path: '/describe/:id',
name: 'Describe',
component: Describe
}

//在使用的時候

this.$router.push({ path: `/describe/${id}` })

//接收頁面獲取值

this.$route.params.id

 

  • params傳參,跳轉的時候不會顯示在url上

//在使用的時候

this.$router.push({ name: 'Describe', params{id: id} })

//接收頁面獲取值

this.$route.params.id

 

  • query傳參,傳餐的時候在url顯示?key=value&key=value

     

    //在使用的時候

    this.$router.push({ path: '/describe', query: { id: id } })

    //接收頁面獲取值
    this.$route.query.id

     

三、路由守衛

1、在之前的版本中,React Router 也提供了類似的 onEnter 鈎子,但在 React Router 4.0 版本中,取消了這個方法。

2、vue的路由守衛主要分為全局守衛和組件守衛兩部分

a.全局守衛

  • beforeEach —— 全局前置鈎子(每個路由調用前都會觸發,根據from和to來判斷是哪個路由觸發)
  • beforeResolve —— 全局解析鈎子(和router.beforeEach類似,區別是在導航被確認之前,同時在所有組件內守衛和異步路由組件被解析之后,解析守衛就被調用)
  • afterEach —— 全局后置鈎子
  • beforeEnter —— 路由獨享的守衛

const router = new VueRouter({
routes: [{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ......
}
}]

})

//與全局前置守衛的方法參數是一樣的

b.組件內守衛

  • beforeRouteEnter —— 在渲染該組件的對應路由被 confirm 前調用,不能獲取組件實例 `this`,因為當守衛執行前,組件實例還沒被創建。
  • beforeRouteUpdate —— 當前路由改變,但是該組件被復用時調用
  • beforeRouteLeave —— 導航離開該組件的對應路由時調用

 

針對beforeRouterEnter不能獲取到this的問題

//beforeRouteEnter守衛不能訪問this,
//因為守衛在導航確認前被調用,因此即將登場的新組件還沒被創建。
//不過,可以你傳通過一個回調給next來訪問組件實例。
//在導航被確認的時候執行回調,並且把組件實例作為回調方法的參數。

beforeRouteEnter (to, from, next) {
next(vm => {
// 通過 `vm` 訪問組件實例
})
}

 

3、完整的導航解析流程

  • 導航被觸發。
  • 在失活的組件里調用離開守衛。
  • 全局調用的beforeEach守衛。
  • 在重用的組件里調用beforeRouteUpdate守衛(2.2+)。
  • 在路由配置里調用beforeEnter
  • 解析異步路由組件。
  • 在被激活的組件里調用beforeRouteEnter
  • 調用全局的beforeResolve守衛(2.5+)。
  • 導航被確認。
  • 全局調用的afterEach鈎子。
  • 觸發DOM更新。
  • 創建組件,用實例好的調用beforeRouteEnter守衛中傳給next的回調函數。

四、總結

1、依據各自框架的風格,有各自的引入方式;

2、提供了不同的基礎組件,但是使用方式卻是大同小異,實現的功能也基本相同;

3、配置方式不同,但是最后結合起來其實都是數據和組件的結合;

4、傳遞參數的方式基本相同,react在url中拼接參數的方式更類似於原生的從URL中獲取參數;

5、react移除了路由守衛,vue依舊保留,但是react的路由守衛其實也可以通過react的高階組件來進行手動實現。

總的來說,vue-router和react-router實際上是依據各自框架以及生態系統來進行具體的實現。呈現給開發者的功能事實上是大同小異的,但是整體的風格和依賴還是以當前框架為基准。無論使用哪個框架,他的生態系統都足夠豐富,足以支撐我們的各種想法的實現。

 

參考文獻:https://cn.vuejs.org/v2/guide/routing.html

    http://react-guide.github.io/react-router-cn/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM