美文网首页
初探react-router v4

初探react-router v4

作者: 我叫傻先生 | 来源:发表于2018-07-06 15:36 被阅读0次

    基本组件

    React Router中有三种类型的组件:路由器组件,路由匹配组件和导航组件

    路由器组件

    对于Web项目,react-router-dom提供<BrowserRouter><HashRouter>路由器。

    两者区别:

    • 地址栏: BrowserRouter地址栏显示方式:http://localhost:8080/abc/def,HashRouter地址栏显示方式:http://localhost:8080/#/abc/def
    • <BrowserRouter>需要server端的配合,每一次跳转页面都向服务器发送一次请求,服务器需要进行处理
    • <HashRouter>不会向服务器发起请求,会找到相对于的模块然后进行渲染
    • 个人觉得如果是静态页面,使用<HashRouter>就好

    <BrowserRouter>使用:
    需要在服务器接受路由,然后返回文件(以node后台为例)

    app.get('*',(request,response)=>{
    
      response.sendFile(path.resolve(__dirname,'../index.html'))
    
    })
    

    <HashRouter>使用:

    import { HashRouter as Router, Route } from 'react-router-dom'
    import Home from './views/home'
    
    <Router>
      <Route path='/' component={Home}/>
    </Router>
    
    
    路由匹配组件<Route><Switch>

    <Switch>可对子元素<Route>进行分组,并仅渲染与当前位置匹配的第一个元素

    <Route>如果匹配到对应的path将会渲染对应组件,如果没有匹配到,则返回null,如果不设置path属性,将会一直渲染
    使用:

    import About from './views/about'
    import Home from './views/home'
    import Services from './views/services'
    
    public render():JSX.Element {
      return (
        <Router>
          <Switch>
            {/* 当路由为 " / " 时 */}
            {/* Home组件将会被渲染 */}
            <Route path='/' component={Home}/>
            {/* About不会渲染,返回null */}
            <Route path='/about' component={About}/>
            {/*上面都不匹配将会渲染Services组件 */}
            <Route component={Services}/>
          </Switch>
        </Router>
      )
    }
    
    
    渲染方式:componentrender,和children

    使用:

    import About from './views/about'
    import Home from './views/home'
    import Services from './views/services'
    
    const AboutCom = (props:any) => {
      return (
        <About />
      )
    }
    
    class App extends React.Component {
      public render():JSX.Element {
        return (
          <Router>
            <Switch>
              {/* 使用component渲染 */}
              <Route path='/home' component={Home}/>
              {/* 使用render渲染 */}
              <Route path='/about' 
              render={AboutCom}/>
              {/* 使用children渲染 */}
              <Route children={AboutCom}/>
            </Switch>
          </Router>
        )
      }
    }
    
    
    <Link>导航

    这个组件主要用于导航,它将会找到相匹配的路由,然后进行渲染,以下为测试结果:

    App.tsx

    <Router>
      <Switch>
        <Route path='/' exact={true} component={Home} />
        <Route path='/linkTest' component={LinkTest} />>
      </Switch>
    </Router>
    

    Home.tsx

    <div>
      <p>这是首页</p>
      <Link to='/linkTest'>点击这个Link跳转到Link组件</Link>
    </div>
    
    

    默认页面是Home,点击Home页面中Link跳转到LinkTest页面,因为这是在App.tsx中定义的,所以将会重新打开一个新的页面

    <Redirect>重定向

    将导航到新的位置,且新位置会覆盖历史堆栈中的位置

    <Router getUserConfirmation={getConfirmation}>
      <Switch>
        <Route path='/' exact={true} component={Home}/>
        <Route path='/home' component={Home}/>
        <Route path='/about' 
        render={AboutCom}/>
        {/* 当地址为:ip::3000/#/anywhere都将跳转到Home页面 */}
        <Redirect to='/'/>
      </Switch>
    </Router>
    

    路径(path)

    <Route path='/roster'/>
    // 当路径名为'/'时, path不匹配
    // 当路径名为'/roster'或'/roster/2'时, path匹配
    // 当你只想匹配'/roster'时,你需要使用"exact"参数, 路由仅匹配'/roster'而不会匹配'/roster/2'
    <Route exact={true} path='/roster'/>
    

    嵌套路由

    在以前的版本中可以使用以下:

    <Route component={App}>
        <Route path="/" components={Home} />
        <Route path="users" components={Users}>
          <Route path="users/:userId" component={Profile} />
        </Route>
    </Route>
    
    

    但是在4.0版本之后就和之前的版本不一样了,详见;react-router官网

    路由传参

    • 配置路由
      <Route path='/user/:id' component={User} />
    • 跳转传参
      • 1.传入string:<Link to={'/user/2'}>跳转传递字符串</Link>
      • 2.传入Object:<Link to={{ pathname:'/user', search: '?sort=name',hash: '#the-hash',state: { fromDashboard: true }}}>跳转传递对象</Link>
    • User页面获取
      • 1.传入string时获取方式:this.props.match.params.id
      • 2.传入Object时获取方式: this.props.location

    1.这里的id和路由中的/user/:id一样,如果路由为 /user/:userId,则获取 this.props.match.params.userId;2.如果参数是对象,则存在this.props.location

    异步加载方案

    安装Loadable

    yarn add react-loadable

    简单封装一次

    router/index.tsx引入使用:

    import * as React from 'react'
    import * as Loadable from 'react-loadable'
    
    interface IRoute {
        component: Promise<React.ComponentClass<any> | React.StatelessComponent<any> | { default: React.ComponentType<any> }>,
        path: string
    }
    
    export const route:IRoute[] = [
        {
            component: import('../views/Support'),
            path: '/support'
        },
        {
            component: import('../views/About'),
            path: '/about'
        },
        {
            component: import('../views/Services'),
            path: '/services'
        }
    ]
    
    function Loading(props: any) {
        console.log(props)
        if (props.error) {
            return <div>Error!</div>
        } else if (props.timedOut) {
            return <div>Taking a long time...</div>
        } else if (props.pastDelay) {
            return <div>loading</div>
        } else {
            return <div>loading</div>
        }
    }
    
    export const loadable = (component: Promise<React.ComponentClass<any> | React.StatelessComponent<any> | { default: React.ComponentType<any> }>) => {
         return Loadable({
            delay: 200,
            loader: () => component,
            loading: Loading,
            timeout: 10000,
        })
    }
    
    调用

    在定义路由的地方调用:

    import * as React from 'react'
    import { Route, Switch } from 'react-router-dom'
    import Nav from '../../component/nav'
    import { loadable, route } from '../../routes'
    
    interface IRouteItem {
        component: Promise<React.ComponentClass<any> | React.StatelessComponent<any> | { default: React.ComponentType<any> }>,
        path: string
    }
    
    export default class Home extends React.Component {
        public render ():JSX.Element {
            return (
                <div>
                    <Nav />
                    <Switch>
                        {route.map((item:IRouteItem, index:number) => {
                            return (
                                <Route path={item.path} component={loadable(item.component)} key={index}/>
                            )
                        })}
                    </Switch>
                </div>
            )
        }
    }
    
    

    Webpack配置Less css加载器

    1.安装less相关依赖

    这是不可逆的操作,它将create-react-app的配置反编译到当前项目,从而完全取得 webpack 文件的控制权,无法回到原来的项目版本!

    自己在使用的时候,它提示让我提交了代码再使用这命令,应该是想让我保存当前版本吧。-.-
    yarn eject 这个命令详见:这里

    2.安装less相关依赖

    npm install less less-loader --save-dev

    3.配置webpack.config.dev.jswebpack.config.prod.js文件(做相同配置)
    • 找到 css-loader所在位置
    • 修改csstest正则 为/\.(css|less)$/,
    • 在use中添加less-loader
    {
        loader: require.resolve('less-loader'),
        options: {
          importLoaders: 1
        }
    }
    
    • 找到exclude,在末尾添加/\.(css|less)$/

    相关文章

      网友评论

          本文标题:初探react-router v4

          本文链接:https://www.haomeiwen.com/subject/czqbuftx.html