React路由深入实战用户登录

35次阅读

共计 5250 个字符,预计需要花费 14 分钟才能阅读完成。

本篇基于 React 路由来实战用户登录功能,会涉及到表单的数据绑定、表单提交和登录判断等新玩意。

续上篇:React 的路由深入

先来创建一个组件 – 登录表单组件

// file:src/components/UserLogin.js

'use strict';

import React from 'react';

export default class UserLogin extends React.Component {construct(props) {super(props);
        this.state = {
            username: '',
            password: ''
        };
    }
    
    render() {
        return <div>
            <h3> 用户登录 </h3>
            <div>
                <span> 用户名:</span>
                <span><input type="text"></span>
            </div>
            <div>
                <span> 密码:</span>
                <span><input type="password"></span>
            </div>
            <div>
                <button> 登录 </button>
            </div>
        </div>
    }
}

绑定表单元素到 state,并且绑定点击事件到按钮

// file:src/components/UserLogin.js

'use strict';

import React from 'react';

export default class UserLogin extends React.Component {construct(props) {super(props);
        this.state = {
            username: '',
            password: ''
        };
    }
    
    setUserInfo(event, key) {
        // input 表单元素会自动绑定一个 event 对象对事件函数
        // event 对象 target 属性等于 input DOM 元素对象,所以 event.target.value 可以获取到当前 input 的 value 值
        let obj = {};
        obj[key] = event.target.value;
        // 更新状态
        this.setState(obj);
    }
    
    render() {
        return <div>
            <h3> 用户登录 </h3>
            <div>
                <span> 用户名:</span>
                <span><input type="text" onInput={(event) => {this.setUserInfo(event, 'username');
                }}></span>
            </div>
            <div>
                <span> 密码:</span>
                <span><input type="password" onInput={(event) => {this.setUserInfo(event, 'password');
                }}></span>
            </div>
            <div>
                <button onClick={() => {
                    // 测试获取的用户名 + 密码
                    alert(this.state.username + this.state.password);
                }}> 登录 </button>
            </div>
        </div>
    }
}

input表单元素会自动绑定一个 event 对象对事件函数

event对象 target 属性等于 input DOM 元素对象,所以 event.target.value 可以获取到当前inputvalue

定义一个用户登录操作类

本篇不涉及后台接口,暂时用固定用户名和密码模拟登录

// file:src/core/Passport.js

'use strict';

export default class Passport {constructor() {
        // 用户登录标识
        this.isLogin = false;
    }
    
    login(username, password, callback) {if (username === 'mi360' && password === '123') {
            // 登录成功
            this.isLogin = true;
            // 将登录成功之后的操作给调用者处理
            callback();} else {
            // 登录失败
            // 这里简单弹出一个消息
            alert('登录失败!');
        }
    }
}

在登录表单中调用登录操作类

// file:src/components/UserLogin.js

'use strict';

import React from 'react';

// 导入登录操作类
import Passport from '../core/Passport';

export default class UserLogin extends React.Component {construct(props) {super(props);
        this.state = {
            username: '',
            password: ''
        };
    }
    
    setUserInfo(event, key) {
        // input 表单元素会自动绑定一个 event 对象对事件函数
        // event 对象 target 属性等于 input DOM 元素对象,所以 event.target.value 可以获取到当前 input 的 value 值
        let obj = {};
        obj[key] = event.target.value;
        // 更新状态
        this.setState(obj);
    }
    
    render() {
        return <div>
            <h3> 用户登录 </h3>
            <div>
                <span> 用户名:</span>
                <span><input type="text" onInput={(event) => {this.setUserInfo(event, 'username');
                }}></span>
            </div>
            <div>
                <span> 密码:</span>
                <span><input type="password" onInput={(event) => {this.setUserInfo(event, 'password');
                }}></span>
            </div>
            <div>
                <button onClick={() => {
                    // 测试获取的用户名 + 密码
                    // alert(this.state.username + this.state.password);
                    
                    // 登录操作
                    const p = new Passport();
                    p.login(this.state.username, this.state.password, () => {
                        // 登录成功时,跳转页面
                        this.props.history.push('/news');
                    })
                    
                }}> 登录 </button>
            </div>
        </div>
    }
}

在我们的路由组件中加上登录组件的路由

// file:src/components/MyRouter.js

'use strict';

import React from 'react';
import News from '../components/News';
import Shop from '../components/Shop';
import Detail from '../components/Detail';

// 用户登录组件
import Login from '../components/UserLogin';

import {
    HashRouter as Router,
    Route,
    Redirect,
    Link
} from 'react-router-dom';

export default class MyRouter extends React.Component {render() {
        return <Router>
            <div>
                <ul className="nav">
                    <li><Link to="/"> 首页 </Link></li>
                    <li><Link to="/products"> 商品 </Link></li>
                    <li><Link to="/news"> 新闻 </Link></li>
                    <li><Link to="/login"> 用户登录 </Link></li>
                </ul>

                <hr/>

                <Route exact path="/" component={Shop} />
                <Route exact path="/products" component={Shop} />
                <Route path="/products/:id" component={Detail} />
                <Route exact path="/news" component={News} />
                <Route path="/login" component={Login} />
            </div>
        </Router>
    }
}

访问页面,预览效果:

输入中正确的用户名和密码会跳到新闻页面!

添加登录判断

给新闻页面加上登录判断,如果没有登录,自动跳转到登录页面

import React from 'react';
import News from '../components/News';
import Shop from '../components/Shop';
import Detail from '../components/Detail';
import Login from '../components/UserLogin';

import {
    HashRouter as Router,
    Route,
    Redirect,
    Link
} from 'react-router-dom';

// 导入用户登录操作类,并实例化
import Passport from '../core/Passport';
let passport = new Passport();

export default class MyRouter extends React.Component {render() {
        return <Router>
            <div>
                <ul className="nav">
                    <li><Link to="/"> 首页 </Link></li>
                    <li><Link to="/products"> 商品 </Link></li>
                    <li><Link to="/news"> 新闻 </Link></li>
                    <li><Link to="/login"> 用户登录 </Link></li>
                </ul>

                <hr/>

                <Route exact path="/" component={Shop} />
                <Route exact path="/products" component={Shop} />
                <Route path="/products/:id" component={Detail} />
                // 使用 render 属性定义处理函数路由跳转判断
                <Route exact path="/news" render={(props) => {if (passport.islogin) {return <News {...props} />
                    } else {return <Redirect to="/login" />}
                }} />
                     // 将用户操作类实例传递给用户登录组件
                <Route path="/login" render={(props) => {return <Login {...props} passport={passport} />
                }} />
            </div>
        </Router>
    }
}

修改用户登录组件使用路由传递过来的用户登录操作类

'use strict';

import React from 'react';
import Passport from '../core/Passport';

export default class UserLogin extends React.Component {constructor(props) {super(props);
        this.state = {
            username: '',
            password: ''
        }
    }

    setUserInfo(event, key) {let obj = {};
        obj[key] = event.target.value;
        this.setState(obj);
    }

    render() {
        return <div>
            <h3> 用户登录 </h3>
            <div>
                <span> 用户名:</span>
                <span><input type="text" onInput={(event) => {this.setUserInfo(event, 'username');
                }} /></span>
            </div>
            <div>
                <span> 密码:</span>
                <span><input type="password" onInput={(event) => {this.setUserInfo(event, 'password')
                }} /></span>
            </div>
            <div>
                <button onClick={() => {let p = this.props.passport == null ? new Passport() : this.props.passport;
                    p.login(this.state.username, this.state.password, () => {
                        // 登录成功时,跳转页面
                        this.props.history.push('/news');
                    });
                }}> 登录 </button>
            </div>
        </div>
    }
}

再次预览访问效果,并且测试新闻未登录下是否能够访问,登录后能否访问!

原文链接:https://www.mi360.cn/articles…

正文完
 0