前言:学习React16+React-Router4 从零打造企业级电商后台管理系统慕课网课程中的项目准备阶段,重点突破登录功能开发和ajax请求封装。
一、基础功能模块的开发登录页
二、登录页面的开发
1.用户名和密码input标签中使用name属性,通过e.target.name可以获取(Bootstrap文档组件-panel完成登录界面)
import React from 'react';
import MUtil from 'util/mm.jsx'
import User from 'service/user-service.jsx'
const _mm = new MUtil();
const _user = new User();
import './index.scss';
class Login extends React.Component{
constructor(props){
super(props);
this.state = {
username: '',
password: '',
redirect: _mm.getUrlParam('redirect') || '/'
}
}
componentWillMount(){
document.title = '登录 - MMALL ADMIN';
}
// 当用户名、密码发生改变
onInputChange(e){
let inputValue = e.target.value,
inputName = e.target.name;
this.setState({
[inputName] : inputValue
});
}
onInputKeyUp(e){
if(e.keyCode === 13){
this.onSubmit();
}
}
// 当用户提交表单
onSubmit(){
let loginInfo = {
username : this.state.username,
password : this.state.password
},
checkResult = _user.checkLoginInfo(loginInfo);
// 验证通过
if(checkResult.status){
_user.login(loginInfo).then((res) => {
_mm.setStorage('userInfo', res);
this.props.history.push(this.state.redirect);
}, (errMsg) => {
_mm.errorTips(errMsg);
});
}
// 验证不通过
else{
_mm.errorTips(checkResult.msg);
}
}
render(){
return (
<div className="col-md-4 col-md-offset-4">
<div className="panel panel-default login-panel">
<div className="panel-heading">欢迎登录 - MMALL管理系统</div>
<div className="panel-body">
<div>
<div className="form-group">
<input type="text"
name="username"
className="form-control"
placeholder="请输入用户名"
onKeyUp={e => this.onInputKeyUp(e)}
onChange={e => this.onInputChange(e)}/>
</div>
<div className="form-group">
<input type="password"
name="password"
className="form-control"
placeholder="请输入密码"
onKeyUp={e => this.onInputKeyUp(e)}
onChange={e => this.onInputChange(e)}/>
</div>
<button className="btn btn-lg btn-primary btn-block"
onClick={e => {this.onSubmit(e)}}>登录</button>
</div>
</div>
</div>
</div>
);
}
}
export default Login;
2.index.html引用jquery的CDN版本
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
3.src->util->mm.jsx封装ajax请求
class MUtil{
request(param){
return new Promise((resolve, reject) => {
$.ajax({
type : param.type || 'get',
url : param.url || '',
dataType : param.dataType || 'json',
data : param.data || null,
success : res => {
//console.log(res)
// 数据请求成功
if(0 === res.status){
typeof resolve === 'function' && resolve(res.data, res.msg);
}
// 没有登录状态,强制登录
else if(10 === res.status){
this.doLogin();
}
else{
typeof reject === 'function' && reject(res.msg || res.data);
}
},
error : err => {
//console.log(err)
typeof reject === 'function' && reject(err.statusText);
}
});
});
}
// 跳转登录
doLogin(){
window.location.href = '/login?redirect=' + encodeURIComponent(window.location.pathname);
}
// 获取URL参数
getUrlParam(name){
// xxxx.com?param=123¶m1=456
let queryString = window.location.search.split('?')[1] || '',
reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"),
result = queryString.match(reg);
//result: ['param=123', '', '123', '&']
return result ? decodeURIComponent(result[2]) : null;
}
// 成功提示
successTips(successMsg){
alert(successMsg || '操作成功!');
}
// 错误提示
errorTips(errMsg){
alert(errMsg || '好像哪里不对了~');
}
// 本地存储
setStorage(name, data){
let dataType = typeof data;
// json对象
if(dataType === 'object'){
window.localStorage.setItem(name, JSON.stringify(data));
}
// 基础类型
else if(['number','string','boolean'].indexOf(dataType) >= 0){
window.localStorage.setItem(name, data);
}
// 其他不支持的类型
else{
alert('该类型不能用于本地存储');
}
}
// 取出本地存储内容
getStorage(name){
let data = window.localStorage.getItem(name);
if(data){
return JSON.parse(data);
}
else{
return '';
}
}
// 删除本地存储
removeStorage(name){
window.localStorage.removeItem(name);
}
}
export default MUtil;
项目接口文档:后台用户接口的response
4.webpack中配置proxy服务端代理跨域
devServer: {
port:8086,
historyApiFallback: {
index: '/dist/index.html'
},
proxy : {
'/manage' : {
target: 'http://admintest.happymmall.com',
changeOrigin : true //如果不加,会用localhost:8086发出请求
},
'/user/logout.do' : {
target: 'http://admintest.happymmall.com',
changeOrigin : true
}
}
}
5.把数据请求接口分到src->service->user-service.jsx中
import MUtil from 'util/mm.jsx'
const _mm = new MUtil();
class User{
// 用户登录
login(loginInfo){
//返回一个Promise对象
return _mm.request({
type: 'post',
url: '/manage/user/login.do',
data: loginInfo
});
}
// 检查登录接口的数据是不是合法
checkLoginInfo(loginInfo){
let username = $.trim(loginInfo.username),
password = $.trim(loginInfo.password);
// 判断用户名为空
if(typeof username !== 'string' || username.length ===0){
return {
status: false,
msg: '用户名不能为空!'
}
}
// 判断密码为空
if(typeof password !== 'string' || password.length ===0){
return {
status: false,
msg: '密码不能为空!'
}
}
return {
status : true,
msg : '验证通过'
}
}
// 退出登录
logout(){
return _mm.request({
type : 'post',
url : '/user/logout.do'
});
}
getUserList(pageNum){
return _mm.request({
type : 'post',
url : '/manage/user/list.do',
data : {
pageNum : pageNum
}
});
}
}
export default User;
6.webpack中配置util和service的resolve
resolve: {
alias : {
page : path.resolve(__dirname, 'src/page'),
component : path.resolve(__dirname, 'src/component'),
util : path.resolve(__dirname, 'src/util'),
service : path.resolve(__dirname, 'src/service'),
}
},
注:项目来自慕课网