react + react-router + redux + ant-Desgin 搭建react管理后台 -- 处理登陆及默认选中侧边栏(六)

前言javascript

  学习总结使用,博客如中有错误的地方,请指正。改系列文章主要记录了搭建一个管后台的步骤,主要实现的功能有:使用路由模拟登陆、退出、以及切换不一样的页面;使用redux实现面包屑;引入使用其余经常使用的组件,好比highchart、富文本等,后续会继续完善。css

  github地址:https://github.com/huangtao5921/react-antDesgin-admin (欢迎Star)html

  项目展现地址:https://huangtao5921.github.io/react-admin/ java

 

1、处理登陆react

  上一篇文章中 react + react-router + redux + ant-Desgin 搭建管理后台 -- 页面布局(五)咱们已经将整个首页的布局呈现了出来,而且点击不一样的侧边栏能跳转到不一样的页面,移入头部的用户头像,有退出登陆的下拉选项,可是功能并无实现,而且咱们随便输入一个路由,好比用户列表的,侧边栏默认选中的一直是首页,咱们接下来处理这2个问题。git

  首先,浏览器输入http://localhost:3000/login,跳转到登陆页,咱们来进行页面布局,并书写基本的逻辑,因为咱们是本地模拟登陆,因此登陆验证成功以后,我在本地缓存了一个登陆成功的信息 loggedIn:true。为 true 表明登陆成功,false或不存在表明未登陆,其实就至关于咱们真实项目中的token。思路是:每次进入登陆页的时候,咱们获取一下本地缓存的loggedIn,若是是登陆的状态,直接跳转到首页。样式写在src/pages/login/login.css中,接下来,将src/pages/login/Login.js代码改写以下:github

import React from 'react';
import { Form, Icon, Input, Button, message } from 'antd';
import { Redirect } from 'react-router-dom';
import './login.css';
class Login extends React.Component {
  handleSubmit = e => {
    e.preventDefault();
    this.props.form.validateFields((err, values) => {
      if (!err) {
        if (values.username === 'admin' && values.password === '123') {
          window.localStorage.setItem('loggedIn', true);
          this.props.history.push('/');
        } else {
          message.error('帐号或密码错误', 1);
        }
      }
    });
  };
  render() {
    const { getFieldDecorator } = this.props.form;
    const loggedIn = window.localStorage.getItem('loggedIn');
    const LoginForm = (
      <div className="login-container">
        <Form onSubmit={this.handleSubmit} className="login-form">
          <div className="sub-title">登 录</div>
          <Form.Item>
            { getFieldDecorator('username', {
              rules: [{ required: true, message: '请输入用户名!' }],
            })(
              <Input prefix={<Icon type="user" className='login-icon' />} placeholder="用户名admin"/>,
            )}
          </Form.Item>
          <Form.Item>
            { getFieldDecorator('password', {
              rules: [{ required: true, message: '请输入密码!' }],
            })(
              <Input prefix={<Icon type="lock" className='login-icon'/>} type="password" placeholder="密码123"/>,
            )}
          </Form.Item>
          <Form.Item>
            <Button type="primary" htmlType="submit" className="login-form-button">登陆</Button>
          </Form.Item>
        </Form>
      </div>
    );
    return (
      loggedIn ? (
        <Redirect to="/"/>
      ) : LoginForm
    );
  }
}
const WrappedNormalLoginForm = Form.create({ name: 'normal_login' })(Login);
export default WrappedNormalLoginForm;

  此时,访问http://localhost:3000/login若是咱们没有登陆,会展现以下,若是咱们登陆过了一次以后,在浏览器输入http://localhost:3000/login,会直接跳转到首页,除非清除掉缓存的loggedIn,这样说明咱们的登陆已经简单的实现了。redux

  
2、处理退出登陆
  接下来咱们再处理一下退出登陆,还记得退出登陆按钮在哪里吗?打开咱们的src/component/layout/HeaderBar.js,找到退出登陆按钮,加上退出登陆的逻辑。被<Route>引入的组件才能读取到this.props.history,因此咱们须要把this.props.history或者将事件传递到子组件中。基于此,咱们须要改变如下文件的代码:浏览器

  routes/index.js中将history对象传递到子组件中:缓存

 
<HeaderBar></HeaderBar>  
改成
<HeaderBar history={this.props.history}></HeaderBar>

  src/component/layout/HeaderBar.js组件中改变如下代码:

HeaderBar中的
<UserInfo/>
改成
<UserInfo history={ props.history }/>

UserInfo组件中加处理函数
handleMenuClick = e => {
  if (e.key === 'outLogin') {
    this.setState({
      visible: false
    });
    window.localStorage.removeItem('loggedIn');
    this.props.history.push('/login');
  }
};

<Menu>
  <Menu.Item key="outLogin">退出登陆</Menu.Item>
</Menu>
改成
<Menu onClick={ this.handleMenuClick }>
  <Menu.Item key="outLogin">退出登陆</Menu.Item>
</Menu>

  最后HeaderBar.js的代码呈现为:

import React from 'react';
import { Layout, Menu, Dropdown, Icon, Breadcrumb } from 'antd';
import customUrl from '../../images/custom.jpeg';
const { Header } = Layout;

class UserInfo extends React.Component {
  state = {
    visible: false,   // 菜单是否显示
  };
  handleMenuClick = e => {
    if (e.key === 'outLogin') {
      this.setState({
        visible: false
      });
      window.localStorage.removeItem('loggedIn');
      this.props.history.push('/login');
    }
  };
  handleVisibleChange = flag => {
    this.setState({ visible: flag });
  };
  render() {
    const menu = (
      <Menu onClick={ this.handleMenuClick }>
        <Menu.Item key="outLogin">退出登陆</Menu.Item>
      </Menu>
    );
    return (
      <Dropdown overlay={ menu } onVisibleChange={ this.handleVisibleChange } visible={ this.state.visible }>
        <div className="ant-dropdown-link">
          <img className="custom-img" src={ customUrl } alt=""/>
          <Icon type="caret-down" />
        </div>
      </Dropdown>
    );
  }
}
const HeaderBar = (props) => {
  return (
    <Header>
      <Breadcrumb>
        <Breadcrumb.Item>首页</Breadcrumb.Item>
      </Breadcrumb>
      <UserInfo history={ props.history }/>
    </Header>
  );
};
export default HeaderBar;

  如今咱们点退出登陆,能够回到登陆页,从登陆点登陆能够跳转到首页,可是在么有登陆的状况下咱们在浏览器中输入http://localhost:3000/仍是能够访问到首页,这是不正常的,只有登陆成功以后才有权限查看首页,没有登陆直接输入地址,咱们应该重置到登陆页,这里相似在登陆页处理逻辑。因此咱们改变一下routes/index.js中的代码,引入Redirect:

// 引入Redirect
import { Route, Switch, Redirect } from 'react-router-dom';

// render函数改为以下:
render() {
    const loggedIn = window.localStorage.getItem('loggedIn');
    const mainPage = (
      <Layout>
        <SiderBar></SiderBar>
        <Layout>
          <HeaderBar history={this.props.history}></HeaderBar>
          <div className="layout-content">
            <Switch>
              <Route exact path="/" component={ Home }/>
              <Route path="/user/connect" component={ Connect }/>
              <Route path="/user/list" component={ List }/>
              <Route path="/tool/rich" component={ Rich }/>
              <Route component={ NotFind }/>
            </Switch>
          </div>
        </Layout>
      </Layout>
    );
    return (
      loggedIn ? (
        mainPage
      ) : (
        <Redirect to="/login"/>
      )
    );
  }

  此时,在没有登陆的状况下,在浏览器中输入首页或者其余页面的url时,会被重置到登陆页,登陆的状况下进入到正确的页面。

2、处理默认选中侧边栏

  接下来处理另一个问题,当咱们在浏览器中输入http://localhost:3000/user/list时,侧边栏默认选中的仍是首页,这是由于咱们在侧边栏组件里面将默认选中和默认展开写死了。这里咱们处理一下,思路是根据每次打开的url的pathname来找到咱们目前访问页面的对应的侧边栏。

defaultOpenKeys: [],       // 默认展开
defaultSelectedKeys: ['/'],   // 默认选中

  接下来,改写src/component/layout/SiderBar.js代码,这里处理的比较死板,只能处理2级的路由,有好的方法能够改写。

  // 新增handleDefaultSelect,每次刷新执行一遍
  componentWillMount() {
    this.handleDefaultSelect();
    const menuList = this.setMenu(menuConfig);
    this.setState({
      menuList
    });
  }

  // 刷新页面,处理默认选中
  handleDefaultSelect = () => {
    let menuConfigKeys = [];
    menuConfig.forEach((item) => {
      menuConfigKeys.push(item.key);
    });
    const pathname = window.location.pathname;
    const currentKey = '/' + pathname.split('/')[1];
    if (menuConfigKeys.indexOf(currentKey) === 1) {
      this.setState({
        defaultOpenKeys: [currentKey],
        defaultSelectedKeys: [pathname],
      });
    }
  }

  此时,在页面输入http://localhost:3000/user/list,会发现用户那一栏被打开,用户列表被选中了。

  目前为止,首页里面处理面包屑部分不会随着路由改变,其余的地方包括登陆以及退出登陆均已经正常了。

  注:交流问题的能够加QQ群:531947619

    

 下一篇:react + react-router + redux + ant-Desgin 搭建react管理后台 -- 引入rudex并处理面包屑(七)

相关文章
相关标签/搜索