react入门笔记之路由

49 篇文章 0 订阅
8 篇文章 0 订阅

路由

基本使用

import React, { lazy, Suspense } from 'react';
// 引入全局css
import './assets/css/index.css';
import { BrowserRouter, Switch, Redirect} from 'react-router-dom';
import PrivateRoute from './utils/privateRoute.js'; //私有路由
// 加载路由页面组件
const Home = lazy(() => import('./pages/home'));
const Login = lazy(() => import('./pages/login'));
const NotFound = lazy(() => import('./pages/notFound'));
{/* 
  路由使用备注
    1.路由的放置顺序非常重要(如果我们在每个路由上都添加 exact 那么它们的顺序可以随意调整,这是另一种选择)
    2.路由组件只在和地址中的路由匹配时才渲染
    3.使用 switch 就会只匹配一组路由中的一个 
    4.注: 访问 "/index/welcome" 时 "/", "/index", "/index/welcome"都会被匹配
    所有前两个要加 exact 做排他性处理
    若将 "/", "/index" 放置到最下边 则不用加 exact
    5.在<Switch> 中,其它的路由没有匹配时,才会渲染重定向组件Redirect
    6.一个路由地址, 可在多个switch中显示多个路由组件
    7.路由守卫功能需要 使用自定义高阶路由组件实现
    8. 配合Suspense和lazy实现路由页面的懒加载  Suspense的fallback中可以提供一个loading组件
    9. PrivateRoute私有路由是和vue类似的路由守卫
*/}
{
  /* react-router v4 无排他性 一个路由可匹配多个组件 
  exact起排他性作用 若不加这个, 
  当访问/login时 index 和login都会被渲染 
  */
}
function App() {
  return (
    <BrowserRouter>
      <Suspense fallback={null}>
        <Switch>
           // isAuth : 是否登录后才能访问(私有路由实现参数)
          <PrivateRoute path="/" component={Home} exact></PrivateRoute>
          <PrivateRoute path="/home" component={Home}></PrivateRoute>
          <PrivateRoute path="/login" component={Login}></PrivateRoute>
          {/* 针对路由地址含有其他内容 可在命名上或放置顺序上动手脚 或者 加上exact*/}
          {/* 第一种方式 加 exact*/}
          {/* <PrivateRoute isAuth={true} path="/articles" exact component={Articles}></PrivateRoute> */}
          {/* params定义传参 */}
          {/* <PrivateRoute isAuth={true} path="/articles/detail/:id" component={ArticlesDetail}></PrivateRoute> */}
           {/* search定义传参 */}
          {/* <PrivateRoute isAuth={true} path="/articles/detail" component={ArticlesDetail}></PrivateRoute> */}
          {/* 第二种方式 调换放置顺序*/}
          {/* 
          <Route path="/articles/detail" component={ArticlesDetail}></Route> 
          <Route path="/articles" component={Articles}></Route>
          */}
          {/* 第三种方式 命名动手脚*/}
          {/* 
          <Route path="/articlesDetail" component={ArticlesDetail}></Route> 
          <Route path="/articles" component={Articles}></Route>
          */}
          <PrivateRoute path="/notFound" component={NotFound}></PrivateRoute>
          <Redirect to="/notFound"/>
        </Switch>
      </Suspense>
    </BrowserRouter>
  );
}
export default App;

私有路由(路由守卫)

import React, { Component } from 'react';
import { Route, withRouter, Redirect} from 'react-router-dom';
// import PropTypes from 'prop-types';
//私有路由,只有登录的用户才能访问
class PrivateRoute extends Component {
    constructor(props){
        super(props);
        this.state = {
           // 是否有存储登录后的信息
            isAuthenticated: true
        }
    }
    doSomesing() {
        console.log('doSomesing');
    }
    render(){
        // render中不能使用this.setState的函数 否则会造成死循环
        // 此处必须返回些什么
        // 返回的内容得是路由跳转相关的 route 或 Redirect  要不继续正常跳转 要不就强制跳转其他页面
        // 返回之前做些操作
        // this.doSomesing();
        console.log('路由钩子 beforeEnterRoute', this.props.match);
     
        let  isAuthenticated =  localStorage.getItem("doctorUserInfo") ? true :false;
        let { component: Component, path, exact=false, strict=false } = this.props;
        {
            if(this.props.isAuth && !isAuthenticated){
                return  <Redirect to="/login"/>
            }else{
            //    return <Route  path={path} exact={exact}  strict={strict}  component={Component} />
                  return <Route  path={path} exact={exact}  strict={strict}  render={(props)=>( <Component {...props} /> )} />
            }
        }
    }
    // //如果没有传递该属性时的默认值
    static defaultProps = {
      // 当前路由是否需要验证登录
        isAuth: false
    }
    // //如果传递该属性,该属性值必须为字符串
    // static propTypes={
    //     path:PropTypes.string.isRequired,
    //     exact:PropTypes.bool,
    //     strict:PropTypes.bool,
    //     component:PropTypes.func.isRequired,
    //     isAuth:PropTypes.bool, //是否需要登录后才能访问
    // }
}
export default withRouter(PrivateRoute);

嵌套路由(子路由)

const Content = lazy(() => import('../content'));
const ArticlesDetail= lazy(() => import('../articlesDetail'));
render() {
        return (
            <div className="layout">
                    <div className="main-box">
                        <Switch>
                             // 当前为 /hoem 路由的子路由
                             // 所有子路由需要以 /home/ xxx 开头
                             // isAuth : 是否登录后才能访问(私有路由实现参数)
                            <PrivateRoute path="/home/content" component={Content}></PrivateRoute>
                            <PrivateRoute isAuth={true} path="/home/articles/detail" component={ArticlesDetail}></PrivateRoute>
                            <Redirect to="/home/content"></Redirect>
                        </Switch>
                    </div>
                </div>
            </div>
        );
    }

路由传参

react定义了多种方式
但需要满足以下几点使用要求
1 书写方便; 2刷新参数不消失;3参数可在地址栏显示(链接在其他地方也可访问)
所以选用search的传参方式

// 路由注册:
<PrivateRoute isAuth={true} path="/home/articles/detail" component={ArticlesDetail}></PrivateRoute>
// 触发跳转
this.props.history.push( `/home/articles/detail/?id=${id}`)
//参数接收
// 此种传参方式 参数写在地址字符串中 需要解析出来
import { querySearch } from '../../utils/utils';
let search = querySearch(this.props.location.search);

querySearch的实现

安转插件
npm i querystring -S
// utils/ulils.js文件
import qs from 'querystring';
// 解析search传参
export const querySearch = (string) => {
  return qs.parse(string.slice(1))
}

另注:可以考虑使用react-router-config, 这是一个辅助react-router的插件,主要是使用配置文件集中式管理路由。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值