本篇基于 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
可以获取到当前input
的value
值
定义一个用户登录操作类
本篇不涉及后台接口,暂时用固定用户名和密码模拟登录
// 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…