zoukankan      html  css  js  c++  java
  • React-Router学习整理

    欢迎大家指导与讨论 : )

      一、前言

        本文摘要:react-router的基本用法动画效果与路由,路由权限控制,路由离开确认,根据路由切分的按需加载,路由组件的属性。本文是笔者在学习时整理的笔记,由于技术水平还不够高,有错误的地方恳请各位指出,共同进步O(∩_∩)O

      二、基本用法

        二、1 路由定义(摘要: Router, Route)

          在一个路由系统中,我们需要定义好路由表。我们需要用Router组件包含我们的路由表,通过Route来声明单个的路由。同时,每个路由应该与它所属的组件一一对应

    render((
      <Router >//开始创建路由表
        <Route path="/" component={App}>//声明每一个路由
          <Route path="/about" component={About}/>
          <Route path="users" component={Users}>//每个路由
            <Route path=":id" component={User}/>//对应一个Component
          </Route>
        </Route>
      </Router>
    ), document.getElementById('example'))

    //其他定义路由表的方法

    import routes from './config/routes'

    render(<Router history={browserHistory} routes={routes}/>, document.getElementById('example'))

        二、2 路由嵌套(摘要: IndexRouter, this.props.children)

          如何实现路由的嵌套呢,与Angular路由一样,路由的嵌套需要两个条件。一、在创建路由表的时候就声明好嵌套的规则(ng中的$stateProvider);二、需要有一个view来安放所要嵌套的子页面(ng中的ui-view)。其中,我们还可以在嵌套层的首个路由声明中,使用IndexRoute来声明该路由下的默认路由(类似于ng中$urlProvider.otherwise)

    //有嵌套与默认页面的路由表
    render((
      <Router >
        <Route path="/" component={App}>
          <IndexRoute component={Index}/>//设置默认页面
          <Route path="/about" component={About}/>
          <Route path="users" component={Users}>
            <IndexRoute component={UsersIndex}/>//设置默认页面
            <Route path=":id" component={User}/>
          </Route>
        </Route>
      </Router>
    ), document.getElementById('example'))
    
    //一个用于安放子页(子路由)的view
    class Users extends React.Component {
      render() {
        return (
          <div>
            <h2>Users</h2>
            {this.props.children}//此处相当于<ui-view>
          </div>
        )
      }
    }

        二、3 路由跳转(摘要: Link,to)

          我们需要一个Link组件帮助我们实现路由的的跳转  <li><Link to="/users" >/users</Link></li> ,最终Link组件会被渲染为<a>标签。to属性是我们所要跳转的路由pathname(类似于ng中的ui-sref / href)

          二、3 . 1 父子路由的参数穿透传递(摘要: to = {`/xx/${xxx}/`} )

            若父路由中包含不确定参数,而我们又想把该参数往下级传递,这时候我们需要这样子做

    //路由配置
          <Route path="user/:userID" component={User}>
            <Route path="tasks/:taskID" component={Task} />
            <Redirect from="todos/:taskID" to="tasks/:taskID" />
          </Route>
    //子级路由
    <li><Link to={`/user/${userID}/tasks/foo`} activeClassName="active">foo task</Link></li>

          二、3 . 2 带参数的路由跳转

    <li><Link      to={{ pathname: '/users/ryan', query: { foo: 'bar' } }} activeStyle={ACTIVE}>/users/ryan?foo=bar</Link></li>

          二、3 . 3 函数内跳转(摘要: this.context.router.push('/'))

              this.context.router.push('/') ,注:这个写法会把跳转载入浏览器历史,若不想留下历史记录则可以 this.context.router.replace('/') 

      三、带有动画效果的路由切换(摘要: ReactCSSTransitionGroup)

        当我们需要在路由切换时带有一定的动画效果时,我们便需要 react-addons-css-transition-group 这个插件了。使用ReactCSSTransitionGroup组件来包含我们需要呈现动画效果的view

    class App extends Component {
      render() {
        return (
          <div>
            <ul>
              <li><Link to="/page1">Page 1</Link></li>
              <li><Link to="/page2">Page 2</Link></li>
            </ul>
    
            <ReactCSSTransitionGroup component="div"  transitionName="example"  transitionEnterTimeout={500}  transitionLeaveTimeout={500}
            >
              {React.cloneElement(this.props.children, {
                key: this.props.location.pathname
              })}
            </ReactCSSTransitionGroup>
               //克隆所有子节点,单独的{this.props.children}没有动画效果
          </div>
        )
      }
    }

      四、路由的权限控制(摘要: onEnter、context.router)

        单页应用路由的权限控制的基本思路是:监听路由的改变,每当路由将要发生改变,我们就使用一个中间服务(该服务介于上一级路由和将要到达路由之间启动),来判断我们是否有进入这个路由的权限,有的话直接进入,没有的话就redirect。在React中,为某个路由进行权限监听的方式是onEnter <Route path="page" component={Page} onEnter={requireCredentials}/> ,该onEnter属性对应连着一个具有判断权限的中间服务。我们通过上一级路由来启动这个服务。假设我们需要从'/form'到'/page'之间做一个判断,在'/form'中填写特定字段后才能成功跳转,否则redirect到'/error'

    //form
    const Form = createClass({
      //省略部分代码
      submitAction(event) {
        event.preventDefault();
         //通过context传输数据
        //通过url的query字段传输数据
        //也可以通过制定其他服务来传输数据
        this.context.router.push({
          pathname: '/page',
          query: {
            qsparam: this.state.value
          }
        })
      },
      render() {
        return (
          <form onSubmit={this.submitAction}>
            //省略部分代码
            <button type="submit">Submit </button>
          </form>
        )
      }
    })
    
    //路由权限控制
    <Route path="page" component={Page} onEnter={requireCredentials}/>
    
    //权限控制的中间服务
    function requireCredentials(nextState, replace, next) {
      //获取传输过来的数据
      if (query.qsparam) {
        serverAuth(query.qsparam)
        .then(
          () => next(),//成功,通过next()成功跳转
          () => {
            replace('/error')//重定向
            next()
          }
        )
      } else {
        replace('/error')
        next()
      }
    }  

         其中,onEnter所指向的函数是 type EnterHook = (nextState: RouterState, replace: RedirectFunction, callback?: Function) => any; 其中,nextState作为第一个参数,其所带的信息有如下:

    type RouterState = {
      location: Location;
      routes: Array<Route>;
      params: Params;
      components: Array<Component>;
    };

           其中,replace函数一旦被使用到,则在函数内部跳转到一个新url,返回时也要带上必要的信息,如下

    type RedirectFunction = (state: ?LocationState, pathname: Pathname | Path, query: ?Query) => void;

       六、路由离开确认(摘要: componentWillMount, this.context.router.setRouteLeaveHook) 

         若我们需要在路由切换,在离开当前页面的时候做一些确认工作,我们可以通过setRouteLeaveHook函数,为离开前执行一些操作

    //Component内部
      componentWillMount() {
        this.context.router.setRouteLeaveHook(
          this.props.route,
          this.routerWillLeave
        )
      }
      
      routerWillLeave() {
        if (xxx)
         //...
      },

      七、根据路由按需加载组件

        按需加载在单页应用中的好处不言而喻,按业务模块切分代码能使首次加载资源所需要的时间大大降低,能在一定程度上增强用户体验。但首先我们需要整理一下我们的项目结构(此demo是按路由切分的,另外还能按业务模块进行切分)

        七 . 1 项目结构

        七 . 2 路由表配置(app.js)

        七 . 3 对应组件的加载配置(routes/hello/index.js和routes/test/index.js)

      八、路由组件的属性(摘要: this.props)

      九、路由Location属性

    type Location = {
      pathname: Pathname;
      search: QueryString;
      query: Query;
      state: LocationState;
      action: Action;
      key: LocationKey;
    };
  • 相关阅读:
    家居有线网络布线方案(转)
    ARP、Tracert、Route 与 NBTStat 命令详解(转)
    集线器、路由器、交换机、第三层交换技术(转)
    C#版nbtstat
    交换机常见故障的一般分类和排障步骤(转)
    Women guojia keneng zai 2015 nian qianhou wancheng di yi ci xiandaihua(拼音化汉字)
    IPv6协议在各操作系统下的安装与配置(转)
    具有字典验证的记事本
    子网掩码计算方法(转)
    最后推荐一篇关于PreEcho的总结论文
  • 原文地址:https://www.cnblogs.com/BestMePeng/p/React_Router.html
Copyright © 2011-2022 走看看