• 通过一个用户管理实例学习路由react-router-dom知识


    我们通过一个用户管理实例来学习react-router-dom

    这个实例包括9个小组件

    App.js 引入组件

    Home.js 首页组件

    User.js 用户管理组件

      -  UserList.js 用户列表组件

      -  UserAdd.js 用户添加组件

      - UserDetail.js  用户详情组件

    Profile.js 个人中心组件

    Login.js  用户登录组件

    Protected.js 处理登录的组件(我们模拟登录的)

    我们先建立一个App组件,作为我们项目引入的组件

    import React, {Component} from 'react';
    //Router 容器,它是用来包裹路由规则的
    //Route 是路由规则
    //BrowserRouter基于h5的。兼容性不好
    //引入react-router-demo
    import {HashRouter as Router, Route,Link,NavLink,Switch} from 'react-router-dom';
    //引入我们需要的组件
    import Home from "./Home";
    import User from "./User";
    import Profile from "./Profile";
    import Login from "./Login";
    import Protected from './Protected'
    //定义一个App组件
    export default class App extends Component {
        render() {
            //定义一个我们选中的状态
            let activeStyle={color:'red'}
            return (
                <Router>
                    <div className="container">
                        <nav className='nav navbar-default'>
                            <div className="container-fluid">
                                <a className="navbar-brand">用户管理</a>
                            </div>
                            <ul className="nav">
                                <li className='navbar-nav'><NavLink exact activeStyle={activeStyle} to="/">首页</NavLink></li>
                                <li className='navbar-nav'><NavLink activeStyle={activeStyle} to="/user">用户管理</NavLink></li>
                                <li className='navbar-nav'><NavLink activeStyle={activeStyle} to="/profile">个人中心</NavLink></li>
                            </ul>
                        </nav>
                        <div>
                            {/*Switch是匹配*/}
                            {/*exact 我们匹配/斜杠时候,就匹配第一个*/}
                            <Switch>
                            <Route exact path="/" component={Home}/>
                            <Route path="/user" component={User}/>
                                <Protected path="/profile" component={Profile}/>
                                <Route path="/login" component={Login}/>
    
                            </Switch>
                        </div>
                    </div>
                </Router>
            )
        }
    }

    App组件使我们引入的组件,在这个组件里面,我们需要注意到最外层的Router

    这个是路由容器,我们路由规则Route需要包裹在日期里面

    Route包含了两个属性,path 和 component

    path指向的路由路径,component指向的是要跳转的组件

    我们路由导航,一般是Link和NavLink两个

    这两个功能一样,都是路由跳转,但是NavLink有一个属性用来显示跳转选中的样式,activeStyle属性,写显示高亮样式的,接收一个对象{}

    在我们路由导航有一个to属性

    to属性是我们路由的要跳转的路径

    下面是User.js 组件,主要包含两个路由NavLink和Route,和上面一个意思,切换两个组件NavLink和Route

    import React, {Component} from 'react'
    import {Link,Route,NavLink} from 'react-router-dom'
    import UsersList from './UsersList'
    import UsersAdd from './UsersAdd'
    import UserDetail from "./UserDetail";
    export default class User extends Component {
        render() {
            let activeStyle={color:'red'}
            return (
                <div className='row'>
                    <div className="col-sm-3">
                        <nav>
                            <ul className="nav nav-stacked">
                                <li><NavLink activeStyle={activeStyle} to="/user/list">用户列表</NavLink></li>
                                <li><NavLink activeStyle={activeStyle} to="/user/add">添加用户</NavLink></li>
                            </ul>
                        </nav>
                    </div>
                    <div className="col-sm-9">
                        <Route path="/user/list" component={UsersList}></Route>
                        <Route path="/user/add" component={UsersAdd}></Route>
                        <Route path="/user/detail/:id" component={UserDetail}></Route>
                    </div>
                </div>
            )
        }
    }

      -  UserAdd.js 用户添加组件

    import React, {Component} from 'react'
    
    export default class UsersAdd extends Component {
        handleSubmit=()=>{
            let username=this.refs.username.value;
            let password=this.refs.password.value;
            let user={username,password,id:Date.now()};
            let users=JSON.parse(localStorage.getItem('USERS')||"[]");
            users.push(user);
            localStorage.setItem('USERS',JSON.stringify(users));
            this.props.history.push('/user/list')
        }
        render() {
            /*
            * history 用来跳转页面
            * location.pathname 用来存放当前路径
            * match代表匹配的结果
            *
            * */
            return (
                <form onSubmit={this.handleSubmit}>
                    <div className="form-group">
                        <label htmlFor="username" className="control-label">
                            用户名
                        </label>
                        <input type="text" className="form-control" ref="username" placeholder="用户名"/>
                    </div>
                    <div className="form-group">
                        <label htmlFor="username" className="control-label">
                            密码
                        </label>
                        <input type="password" className="form-control" ref="password" placeholder="密码"/>
                    </div>
                    <div className="form-group">
    
                        <input type="submit" className="btn btn-danger" />
                    </div>
                </form>
            )
        }
    }

    我们将用户添进去的数据,在页面缓存,方便我们用户列表页渲染

    localStorage.setItem('USERS',JSON.stringify(users));
    缓存完成后跳转到列表详情页面userList
    this.props.history.push('/user/list')

     -  UserList.js 用户列表组件

    import React, {Component} from 'react'
    import {Link} from 'react-router-dom'
    export default class UsersList extends Component {
        constructor(){
            super();
            this.state={users:[]}
        }
        componentWillMount(){
            let users = JSON.parse(localStorage.getItem('USERS') || "[]");
            this.setState({users});
        }
        render(){
            return (
               <ul className="list-group">
                   {
                       this.state.users.map((user,index)=>(
                           <li key={index} className="list-group-item">
                               <span>用户名:</span>
                               <Link to={`/user/detail/${user.id}`}>{user.username}</Link>
                              <span className="btn btn-danger" onClick={()=>{
                                  let users=this.state.users.filter(item=>item.id!=user.id)
                                  this.setState({users});
                              }}>删除</span>
                           </li>
                       ))
                   }
               </ul>
            )
        }
    }
    
    

    componentWillMount()是组件挂载完成后的组件周期函数

    在这个钩子函数里面,我们去userAdd存储的USERS数据,然后渲染到页面上去
    <Link to={`/user/detail/${user.id}`}>{user.username}</Link>

    这里面我们跳转到个人信息详情里面,把每个人的用户id带上

    然后我们用户详情页面UserDetail.js 组件

    import React, {Component} from 'react'
    
    export default class UserDetail extends Component {
    
    
    
        render() {
            // let user=this.props.location.state.user
            let users = JSON.parse(localStorage.getItem('USERS')||"[]");
            let id = this.props.match.params.id;
            let user = users.find(item=>item.id == id);
            return (
                <table className="table table-bordered">
                    <thead>
                    <tr>
                        <th>ID</th>
                        <th>用户名</th>
                        <th>密码</th>
                    </tr>
                    </thead>
                    <tbody>
                        <tr>
                        <td>{user.id}</td>
                        <td>{user.username}</td>
                        <td>{user.password}</td>
                        </tr>
                    </tbody>
                </table>
            )
        }
    }

    let id = this.props.match.params.id;

    let user = users.find(item=>item.id == id);

    通过match里面获取到路由带过来的id

    然后判断users里面id相同的那一项

    然后渲染到页面上去

    ,然后我们判断登录,如果没有登录,就去登录,登录后才能看用户管理

    import React from 'react';
    import {Route, Redirect} from 'react-router-dom';
    //函数组件
    //把属性对象中的Component属性取出来赋给comp,把其它属性取出来赋给other对象
    //再把other对象的全部属性取出来赋给Route
    // component=组件
    // render函数 当路由匹配的时候,渲染的是render方法的返回值
    export default function ({component: _comp, ...rest}) {
        return <Route {...rest} render={
            props => localStorage.getItem('login') ? <_comp/> :
                <Redirect to={{pathname: '/login', state: {from: props.location.pathname}}}/>
        }/>
        return null;
    }

    如果没有登录,我们就进入登录组件,其实我们模拟登录就是设置了一个缓存login为true,模拟权限,真实项目中,我们通过后台接口来限制,路由跳转

    import React, {Component} from 'react';
    export default class Login extends Component {
        handleClick = ()=>{
            localStorage.setItem('login','true');
            console.log(this.props);
            this.props.history.push(this.props.location.state.from);
        }
        render() {
            return (
                <div>
                    <button
                        onClick={this.handleClick}
                        className="btn btn-primary">登录
                    </button>
                </div>
            )
        }
    }

     后面,我们首页Hone和Profile两个组件,基本就是展示个人信息的,就是渲染,所以我就没有必要写了!

    总体完成,路由嵌套路由,然后通过路由参数分辨路由不同的信息

    
    
    
    
    
  • 相关阅读:
    java 多线程
    数据结构与算法-----快速排序
    JS 强制类型转化
    VS Code 编辑器
    MySQL8数据库安装配置和启动
    listview更改选中时item背景色(转)
    Android下用程序的方法为ListView设置分割线Divider样式
    listview android:cacheColorHint,android:listSelector属性作用
    Android手动显示和隐藏软键盘
    android调试debug快捷键
  • 原文地址:https://www.cnblogs.com/null11/p/7647626.html
Copyright © 2020-2023  润新知