zoukankan      html  css  js  c++  java
  • React router的Route应用

    Route 是 React Router中用于配置路由信息的组件,每当有一个组件需要根据 URL 决定是否渲染时,就需要创建一个 Route。

    react-router 中的很多特性都与 React 保持了一致,比如它的声明式组件、组件嵌套,当然也包括 React 的状态机特性。

    1.path

    每个Route都需要一个path属性,path属性是一个url,当URL匹配一个Route时,这个Route中定义的组件就会被渲染出来。

    2.Route渲染组间的方式

    (1)Component

    component的值是一个组件,当URL和Route匹配时,Component属性定义的组件就会被渲染。

    <Route path="/mycom" component={MyCom} >

    (2)Render

    Render 值是一个函数,这个函数返回一个React元素。这种方式方便地为待渲染的组件传递额外的属性。

    <Route path=‘/mycom’  render={(props) => {
    
     <MyCom {…props} data={extraProps} /> //MyCom 组件接收了一个额外的data属性
    
    }}>
    
    </Route>

    (3)children

    Children的值也是一个函数,函数返回要渲染的React元素。与前面不同是,无论是否匹配成功,children返回的组件都会被渲染。匹配不成功时,match属性为null。

    <Route path="/myCom" render={(props) => {
    
     <div className={props.match ? 'active' : ''}>
    
       <Foo {…props} data={extraProps} />
    
     </div>
    
    }}
    
    </Route>

    如果Route匹配当前URL,待渲染元素的根节点div的class将设置成active.

    3.多级路由

    在路由里面继续写路由,挂载组件,就可以实现多级路由。路由嵌套实现。

    <Route path=‘/myCom’ component={myCom}>
      <Route path=‘/myCom/sonCom’ component={SonCom}></Route>
    </Route>

    如果多级路由嵌套的层次太深,那我们写子路由的path就会特别麻烦,所以可以这样:

    <Route path=‘/mycom’  render={(props) => {
      <Route path={`${props.match.path}/sonCom`} component={SonCom} />
    }}>
    </Route>

    Match是从props解构出来,match.path就是我们当前这个路由的路径,这样不管嵌套多深,都可以写上一级的路由

    4.动态传参

    /foodlist/:id,传过去的值就在路由挂载组件的props中,props里有个match, match中有个params, 注意:props只在路由挂载的组件才有

    <Route path=‘/foodlist/:id’ component={MyCom} />

    MyCom 组件的props中就可以获取到id

    可以在一个组件中用 this.props.history.push(“/path”, {name: “hellow”}), 来进行传参,传过去的值在props.location.state中

    5.withRouter

    一个典型的高阶组件,如果我们既想实现点击跳转,又不想用Link的a标签,我们可以用withRouter给我们吐出来一个实现点击跳转路由的组件。 Eg.

    import { withRouter } from 'react-router-dom’;
    
    //使用自定义的组件:
    
    <CustomNavLink to="/food">food</CustomNavLink>
    
    <CustomNavLink to="/wiki">wiki</CustomNavLink>
    
    <CustomNavLink to="/profile">profile</CustomNavLink>
    
    //给自定义组件实现点击功能:
    
    const CustomNavLink = withRouter(class EnhenceCustomNavLink extends Component {
    
        render () {
    
          return (
    
            <li onClick={this.goto.bind(this)}>
    
              {
    
                this.props.location.pathname === this.props.to ? '>' + this.props.children : this.props.children
    
              }
    
            </li>
    
          )
    
        }
    
        goto () {
    
          this.props.history.push(this.props.to)
    
        }
    
    })

    假如你的组件没有路由信息,你可以使用withRouter(component)将这个组件包起来,props里面就有路由信息了。

    这里我们顺便了解下前端路由的两种模式:Hash模式和History模式

    1、Hash 模式:

     这里的 hash 就是指 url 尾巴后的 # 号以及后面的字符。Hash 也称作锚点,用来做页面的定位,可以使对应的id的元素显示在可视区域内。

    Hash值的变化不会导致浏览器向服务器发出请求,而且hash改变会触发hashchange事件,浏览器的前进和后退也能对其进行控制,在html5的history出现前,基本就是使用hash来实现前段路由的。

    window.location.hsah = 'qq' //设置url的hash,会在当前url后加上#qq
    
    var hash = window.location.hsah //qq
    
    Window.addEventListener('hashchange', function() {
    
     //监听hash变化,点击浏览器的前进后退会触发
    )

     

    2, History模式

    已经有 hash 模式了,而且 hash 能兼容到IE8, history 只能兼容到 IE10,为什么还要搞个 history 呢?

    首先,hash 本来是拿来做页面定位的,如果拿来做路由的话,原来的锚点功能就不能用了。其次,hash 的传参是基于 url 的,如果要传递复杂的数据,会有体积的限制,而 history 模式不仅可以在url里放参数,还可以将数据存放在一个特定的对象中。

    window.history.pushState(state, title, url)
    // state:需要保存的数据,这个数据在触发popstate事件时,可以在event.state里获取
    // title:标题,基本没用,一般传 null
    // url:设定新的历史记录的 url。新的 url 与当前 url 的 origin 必须是一樣的,否则会抛出错误。url可以是绝对路径,也可以是相对路径。
    /*如 当前url是 https://www.baidu.com/a/,执行history.pushState(null, null, './qq/'),则变成 https://www.baidu.com/a/qq/,执行history.pushState(null, null, '/qq/'),则变成 https://www.baidu.com/qq/ */
    
    window.history.replaceState(state, title, url)
    // 与 pushState 基本相同,但这是修改当前历史记录,而 pushState 是创建新的历史记录
    
    window.addEventListener(“popstate”, funbction(){
      // 监听浏览器前进后退事件,pushState 与 replaceState 方法不会触发     
    });
    
    window.history.back() // 后退
    window.history.forward()// 前进
    window.history.go(1) //前进一步,-2为后退两步,window.history.length可以查看当前历史堆栈中页面的数量

    history 模式改变 url 的方式会导致浏览器向服务器发送请求,需要在服务器端做处理:如果匹配不到任何静态资源,则应该始终返回同一个 html 页面。

    我们再顺便了解下:用户访问的URL后面加入# 号的知识

    1. #号的含义:

    #号代表网页中的一个位置,# 号后面的内容就是该位置的一个标记,eg.

    http://www.example.com/index.html#print

    访问该地址,浏览器页面会自动滚动到print 位置,print显示在可视区域

    //为页面指定位置的有两种方式:
    1)加锚点 <a name=“print”></a> 
     (2)<div id=“print”></div>

    2.Http请求不包括#部分

    比如访问上面的链接,实际发出的请求是:

    GET /index.html HTTP/1.1
    
    Host: www.example.com

    #号后面的任何字符,都会被解析为位置标志符,比如:

    http://www.example.com/?color=#fff

    实际发出的请求是:

    GET /?color= HTTP/1.1
    Host: www.example.com

    这并不是我们所期望的,可以对#号转义 #转为23%

    http://www.example.com/?color=23%fff

     

    3.改变网页的#号部分,不会触发网页的重载

    http://www.example/com/index.html#location1
    http://www.example.com/index.html#location2 
    //改变#号后面的内容,不会重新触发服务器的请求,也就是#号后面的内容对服务器端没影响

    4.改变#号后面的内容,可以修改浏览器的访问历史

    每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用"后退"按钮,就可以回到上一个位置。

    5.window.location.hash 可以读到#号后面的内容

    来判断网页是否发生了变化,给window.location.hash赋值时,就是增加了一条浏览器的历史访问记录

    6. onhashchange 是HTML5增加的可以监听hash改变的接口:

    window.onhashchange = func;
    <body onhashchange="func();">
    window.addEventListener("hashchange", func, false);

    对于不支持onhashchange的浏览器,可以用setInterval监控location.hash的变化。

    7.Google抓取#的机制

    默认情况下,Google的网络蜘蛛忽视URL的#部分。

    如果你希望Ajax生成的内容被浏览引擎读取,那么URL中可以使用"#!",Google会自动将其后面的内容转成查询字符串_escaped_fragment_的值。

     

     

     

  • 相关阅读:
    L2-1 功夫传人 (25分)
    7-11 家庭房产(25 分)
    7-11 玩转二叉树 (25分)
    7-10 排座位 (25分)
    7-12 最长对称子串 (25分)
    7-10 树的遍历 (25分)
    STL
    Max Gcd
    水果
    Rails
  • 原文地址:https://www.cnblogs.com/torri/p/11118754.html
Copyright © 2011-2022 走看看