• react03


    react脚手架:

      全局安装:npm i create-react-app -g

      查看脚手架版本:create-react-app -V

    脚手架创建项目:

      create-react-app myrouter(要求node版本最低是v10.14.2)

    react路由:

      安装:npm i react-router-dom

      基本使用:

        1、路由的形式:

          hash路由:HashRouter

          history路由:BrowserRouter

          路由的所有配置必须在HashRouter或BrowserRouter的包裹范围之内

        2、路由的显示:

          route:

            作用:用来配置路由以及路由的显示

            配置项:

              path:路由匹配的路径

              component:当路径匹配成功后需要渲染的组件(值为组件名称)

              render:当路径匹配成功后需要渲染的组件(值是一个函数)

              exact:完全匹配

        3、路由跳转的方式:

          ①a标签

              <a href="#/home">首页</a>
              <a href="#/classify">分类</a>
              <a href="#/order">订单</a>

          ②Link(没有选中标识的,使用场景:返回)

              <Link to='/home'>首页</Link>
              <Link to='/order'>订单</Link>
              <Link to='/classify'>分类</Link>

            如果重复点击某个路由会报警告:

              

              警告:哈希历史不能推送相同的路径;新的条目不会被添加到历史堆栈中

          ③NavLink(使用场景:底部导航、有选中标识的导航)

            

              <NavLink to='/home' activeClassName='aaa' activeStyle={{background:'yellow'}}>首页</NavLink>
              <NavLink to='/order'>订单</NavLink>
              <NavLink to='/classify'>分类</NavLink>

            

            配置项:

              to:需要跳转的路径

              activeClassName:更改选中后的标识

              activeStyle:选中后的样式

          ④编程式导航

        4、路由传值:

          ①动态路由:(地址栏上有参数:details/xxx/xxx,刷新不丢失)

            在定义的时候通过 /:属性 的方式来定义传递的属性

              

            在路由跳转的时候通过 /值 的方式进行传值

              

            在需要接收数据的页面通过 this.props.match.params 来接收

              

          ②query传值:(地址栏上有参数:details?id=xxx&name=xxx,刷新不丢失)

            路由:

            在路由跳转的时候通过 query 进行传值

              

            在需要接收数据的页面通过 this.props.location.search 来接收(?id=0&name=%E9%A6%99%E8%95%89)

              

          ③内存传值:(地址栏上没有参数,刷新会丢失)

            路由:

            在路由跳转的时候通过 to={{pathname:'', query:{}}} 进行传值

              

            在需要接收的页面通过 this.props.location.query 来接收

              

        5、路由嵌套:

          

        6、编程式导航:

          this.props.history.push()

            

            

          this.props.history.goBack()
          this.props.history.goForward()
          this.props.history.go()
          this.props.history.replace()

        7、component渲染和render渲染的区别:

          ①在route组件中通过component属性进行页面渲染的时候会默认的给当前组件传递三个值(history match location)

            

          ②render渲染的时候可以渲染组件也可以渲染标签

            

          ③render渲染的时候可以进行传值

            

          ④一般情况下会通过render的方式进行路由的嵌套

          ⑤render可以进行更多的业务逻辑

        8、路由重定向:

          import {Redirect} from 'react-router-dom'

          

        9、Switch

          作用:只匹配一个路由

        10、路由懒加载:

          ①安装:npm i react-loadable

          ②引入并使用:

            

        11、withRouter:

          高阶组件:

            作用:可以给当前组件的props传入一个对象,这个对象就是路由的三个值{history match location}

          当使用render方式渲染组件时,如果没有手动去传路由的三个值:

            

          此时在order组件中的this.props是一个空对象:

            

          使用withRouter将组件包裹:

            

           此时再打印this:

            

          说明withRouter给当前被包裹的组件传递了路由的三个值,就可以正常使用编程式导航等功能了。

    路由表封装:

      1、在components中新建index.js文件,将所有的页面都用懒加载的方式引入,整体导出出去

      2、src下新建router/index.js:将路由放入路由表中

            import {
              Home,
              Classify,
              HotMovie,
              CommingMovie,
              ClassifyOrder,
              Order,
              Login
            } from '../components'
    
            // 有layout布局的路由表
            export const layoutRoutes = [
              {
                path: '/home',
                component: Home,
                icon: '',
                meta: {}
              },
              {
                path: '/classify',
                component: Classify,
                icon: '',
                meta: {},
                children: [
                  {
                    path: '/classify/hotMovie',
                    component: HotMovie,
                    meta: {}
                  },
                  {
                    path: '/classify/commingMovie',
                    component: CommingMovie,
                    meta: {}
                  },
                  {
                    path: '/classify/order',
                    component: ClassifyOrder,
                    meta: {}
                  }
                ]
              },
              {
                path: '/order',
                component: Order,
                icon: '',
                meta: {}
              }
            ]
    
            // 没有layout布局的路由表
            export const notLayoutRoutes = [
              {
                path: '/login',
                component: Login,
                meta: {}
              }
            ]
    
            // 所有路由的配置项
            export const configRoutes = layoutRoutes.concat(notLayoutRoutes)

      3、src下新建utils/routesEach.js:传入路由表返回对应的组件,并且模拟vue中路由守卫

            import React, { Fragment } from 'react'
            import { Switch, Redirect, Route } from 'react-router-dom'
    
            export default (routes) => {
              function routesEach(routeConfig) {
                return routeConfig.map((item) => {
                  if (item.children) {
                    return (
                      <Route
                        path={item.path}
                        key={item.path}
                        render={() => {
                          return (
                            <Fragment>
                              <Route component={item.component}></Route>
                              <Switch>
                                <Redirect
                                  from={item.path}
                                  to={item.children[0].path} // 重定向到第一个路由
                                  exact
                                ></Redirect>
                                {item.children.map((child) => {
                                  return (
                                    <Route
                                      path={child.path}
                                      key={item.path}
                                      render={() => {
                                        return isAuthRequired(child) // 权限验证
                                      }}
                                    ></Route>
                                  )
                                })}
                              </Switch>
                            </Fragment>
                          )
                        }}
                      ></Route>
                    )
                  } else {
                    return (
                      <Route
                        path={item.path}
                        key={item.path}
                        render={() => {
                          return isAuthRequired(item)
                        }}
                      ></Route>
                    )
                  }
                })
              }
              // 权限验证:路由守卫
              function isAuthRequired(item) {
                // 先判断当前路由是否需要权限验证
                if (item.meta.authRequired) {
                  // 当前路由需要权限验证,判断token是否存在
                  if (localStorage.getItem('token')) {
                    return <item.component></item.component>
                  } else {
                    return <Redirect to="/login"></Redirect>
                  }
                } else {
                  return <item.component></item.component> // 不需要权限验证的路由可以直接返回
                }
              }
              return routesEach(routes)
            }

      4、app.js

  • 相关阅读:
    POJ 2349 Arctic Network
    OpenJudge 东方14ACM小组 / 20170123 06:Challenge 3
    OpenJudge 东方14ACM小组 / 20170123 02 岛屿
    Best Coder Lotus and Characters
    洛谷 P 1164 小A点菜
    楼房
    虫食算
    斗地主
    国王游戏
    最优贸易
  • 原文地址:https://www.cnblogs.com/wuqilang/p/14267565.html
Copyright © 2020-2023  润新知