zoukankan      html  css  js  c++  java
  • 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/

  • 相关阅读:
    Java中RuntimeException和Exception
    RuntimeException和Exception的区别
    Spring事务异常回滚
    iOS 卖票中多线程分析;
    凝视转换(部分)
    HDU 5386 Cover(模拟)
    iOS开发之软键盘使用小技巧
    【每日算法】高速幂
    CKEditor高级编辑器
    iOS开发 剖析网易新闻标签栏视图切换(addChildViewController属性介绍)
  • 原文地址:https://www.cnblogs.com/marui01/p/13215468.html
Copyright © 2011-2022 走看看