详解前端路由实现与react-router使用姿势


Posted in Javascript onAugust 07, 2017

路由

对于有过SPA开发经验的人来说,路由这个名词并不陌生,前端的路由和后端的路由在实现技术上不一样,但是原理都是一样的。在 HTML5 的 history API 出现之前,前端的路由都是通过 hash 来实现的,hash 能兼容低版本的浏览器。它的 URI 规则中需要带上 #。Web 服务并不会解析 hash,也就是说 # 后的内容 Web 服务都会自动忽略,但是 JavaScript 是可以通过 window.location.hash 读取到的,读取到路径加以解析之后就可以响应不同路径的逻辑处理。

简单介绍AngularJs UI-Router路由

如果你有过AngularJS开发经验,#并不陌生,angularjs有自己官方实现的路由体系,也有比较具有代表性的第三方嵌套路由机制UI-Router; 如下代码块所示:

.state("main.list",angularAMD.route({
    url : '/list/:params',//url &参数
    views : {
      "header@main" : angularAMD.route({
        templateUrl : 'simple/view/main/html/main/Header.html',
        controller:'HeadController',
        controllerUrl:[ ****.js
                  ]
      }),
      "menu@main" : angularAMD.route({
        templateUrl : 'simple/view/main/html/main/MenuModule.html',
        controller : "MenuController",
        controllerUrl:[ ****.js]
      }),
      "mainContent@main":angularAMD.route({
        templateUrl : 'simple/view/main/html/main/MainContent.html'
      })
    }
  }))

state()函数的第一个参数就是路由,“main.list” 是一个嵌套路由机制,当页面跳转到 “main.list”路由下时会先加载 state(“main”,*)下的模块及其资源(html,js等),随后加载state(”main.list”)下的模块和资源(html,js等),实现路由嵌套;

react-router

-先上一段代码

<Router history={ hashHistory }>
  <Route path='/' component={CoreLayout}>
  <IndexRoute component={HomeView}/>
  <Route path=”/HODE_ROUTE/:param“ component={HomeView}/>
  <Route path=“ /AUDIT_ROUTE/:param" component={AuditView}/>
  <Route path=“/CHART_ROUTE” component={ChartView}/>
  </Route>
</Router>

React-router以jsx语法类似于DOM结构的形式实现router嵌套;与AngularJs 的UI-Router看似差别很大,实则思想雷同;

Angular的实现逻辑:

跳转=》state=》module=》静态资源(js,css,html)=》show(页面展示)

react-router的实现逻辑:

跳转=》path=》component=》静态资源(js,css,html)=》show(页面展示)
本文主要讲react-router,下面简单介绍react-router的使用姿势:

react-router常用组件入门

嵌套路由

<Router history={hashHistory}>
 <Route path="/" component={App}>
  <Route path="/repos" component={Repos}/>
  <Route path="/about" component={About}/>
 </Route>
</Router>

上面代码中,用户访问/repos时,会先加载App组件,然后在它的内部再加载Repos组件。

<App>
 <Repos/>
</App>

子路由也可以不写在Router组件里面,单独传入Router组件的routes属性

let routes = <Route path="/" component={App}>
 <Route path="/repos" component={Repos}/>
 <Route path="/about" component={About}/>
</Route>;

<Router routes={routes} history={browserHistory}/>

path 属性

Route组件的path属性指定路由的匹配规则,看下面例子

<Route path="inbox" component={Inbox}>
  <Route path="messages/:id" component={Message} />
</Route>

上面代码中,当用户访问/inbox/messages/:id时,会加载下面的组件。

<Inbox>
 <Message/>
</Inbox>

IndexRoute 组件

类似index.html ,默认加载组件,下面代码默认加载home组件

<Router>
 <Route path="/" component={App}>
  <IndexRoute component={Home}/>
  <Route path="accounts" component={Accounts}/>
  <Route path="statements" component={Statements}/>
 </Route>
</Router>

现在,用户访问/的时候,加载的组件结构如下。

<App>
 <Home/>
</App>

Redirect 组件

Redirect组件用于路由的跳转,即用户访问一个路由,会自动跳转到另一个路由。

<Route path="inbox" component={Inbox}>
 {/* 从 /inbox/messages/:id 跳转到 /messages/:id */}
 <Redirect from="messages/:id" to="/messages/:id" />
</Route>

现在访问/inbox/messages/5,会自动跳转到/messages/5。

Link

Link组件用于取代a标签,生成一个链接,允许用户点击后跳转到另一个路由。它基本上就是a标签的React 版本,可以接收Router的状态。

表单处理

Link组件用于正常的用户点击跳转,但是有时还需要表单跳转、点击按钮跳转等操作。这些情况怎么跟React Router对接呢?

第一种方法是使用browserHistory.push

handleSubmit(event) {
  event.preventDefault()
  const userName = event.target.elements[0].value
  const repo = event.target.elements[1].value
  const path = `/repos/${userName}/${repo}`
  browserHistory.push(path)
 }

${userName} 一种后端语言常用的表达式写法,可在字符串中取变量

handleSubmit(event) {
  // ...
  this.context.router.push(path)
 },

第二种方法是使用context对象。

export default React.createClass({

 // ask for `router` from context
 contextTypes: {
  router: React.PropTypes.object
 },

 handleSubmit(event) {
  // ...
  this.context.router.push(path)
 },
})

多人协作开发router文件管理

一般一个项目都会有一个统一的router文件,相当于一个router池,不同的请求,请求router池中所匹配的路径,加载请求所需页面。 but 。。。 每个开发者开发一个组件都会需要配置路由,会导致router文件不易管理,容易导致冲突,甚至故障。 so。。,也许,可能可以每个组件文件夹下对于一个XXX.router 文件,前端代码打包上传到线上时触发某个钩子函数,将XXX.router文件统一合并到中央router文件中,从而避免多人操作router文件。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery 圆形旋转图片滚动切换效果
Jan 19 Javascript
jqeury eval将字符串转换json的方法
Jan 20 Javascript
输入自动提示搜索提示功能的javascript:sugggestion.js
Sep 02 Javascript
js控制frameSet示例
Sep 10 Javascript
理解 JavaScript Scoping &amp; Hoisting(二)
Nov 18 Javascript
Angular.js实现注册系统的实例详解
Dec 18 Javascript
浅谈js算法和流程控制
Dec 29 Javascript
jQuery EasyUI 页面加载等待及页面等待层
Feb 06 Javascript
解决vue中使用swiper插件问题及swiper在vue中的用法
Apr 04 Javascript
JS实现模糊查询带下拉匹配效果
Jun 21 Javascript
Vuex实现购物车小功能
Aug 17 Javascript
微信小程序对图片进行canvas压缩的方法示例详解
Nov 12 Javascript
React中使用collections时key的重要性详解
Aug 07 #Javascript
react路由配置方式详解
Aug 07 #Javascript
深入理解vue.js中$watch的oldvalue与newValue
Aug 07 #Javascript
JavaScript调试之console.log调试的一个小技巧分享
Aug 07 #Javascript
react native仿微信PopupWindow效果的实例代码
Aug 07 #Javascript
jquery+css实现简单的图片轮播效果
Aug 07 #jQuery
bootstrap table表格客户端分页实例
Aug 07 #Javascript
You might like
PHP输出控制功能在简繁体转换中的应用
2006/10/09 PHP
不错的一篇面向对象的PHP开发模式(简写版)
2007/03/15 PHP
PHP __autoload()方法真的影响性能吗?
2012/03/30 PHP
php实例分享之二维数组排序
2014/05/15 PHP
PHP单例模式是什么 php实现单例模式的方法
2016/05/14 PHP
ThinkPHP 3.2.2实现事务操作的方法
2017/05/05 PHP
Jquey拖拽控件Draggable使用方法(asp.net环境)
2010/09/28 Javascript
JQuery中DOM加载与事件执行实例分析
2015/06/13 Javascript
javascript验证内容为数字以及长度为10的简单实例
2016/08/20 Javascript
vue2.0实现倒计时的插件(时间戳 刷新 跳转 都不影响)
2017/03/30 Javascript
Vue项目中quill-editor带样式编辑器的使用方法
2017/08/08 Javascript
Bootstrap Table 搜索框和查询功能
2017/11/30 Javascript
vue-cli 组件的导入与使用教程详解
2018/04/11 Javascript
JS中call和apply函数用法实例分析
2018/06/20 Javascript
vue 使用element-ui中的Notification自定义按钮并实现关闭功能及如何处理多个通知
2019/08/17 Javascript
layui使用表格渲染获取行数据的例子
2019/09/13 Javascript
js实现图片上传即时显示效果
2019/09/30 Javascript
VUEX 数据持久化,刷新后重新获取的例子
2019/11/12 Javascript
vue.js实现点击图标放大离开时缩小的代码
2021/01/27 Vue.js
[02:38]DOTA2亚洲邀请赛 IG战队巡礼
2015/02/03 DOTA
[01:55]TI9显影之尘系列 - Evil Geniuses
2019/08/22 DOTA
Flask的图形化管理界面搭建框架Flask-Admin的使用教程
2016/06/13 Python
python使用pyqt写带界面工具的示例代码
2017/10/23 Python
解决python3捕获cx_oracle抛出的异常错误问题
2018/10/18 Python
python将txt文件读入为np.array的方法
2018/10/30 Python
解决pycharm的Python console不能调试当前程序的问题
2019/01/20 Python
不到40行代码用Python实现一个简单的推荐系统
2019/05/10 Python
python requests模拟登陆github的实现方法
2019/12/26 Python
Python post请求实现代码实例
2020/02/28 Python
Python批量将图片灰度化的实现代码
2020/04/11 Python
Perfume’s Club美国官网:西班牙第一家在线美容店
2020/06/10 全球购物
盛大二次面试题
2016/11/18 面试题
物流管理专业推荐信
2014/09/06 职场文书
应收账款管理制度
2015/08/06 职场文书
小学毕业教师寄语
2019/06/21 职场文书
Python实现Telnet自动连接检测密码的示例
2021/04/16 Python