react项目实战(权限模块开发三) 登陆界面开发
2017-07-19 11:00
597 查看
首先上效果图:
选择皮肤下拉。
功能分析:
点击记住用户名区域,checkbox选中,再点击则checkbox取消选中。
点击皮肤选择框,会显示皮肤下拉。
如果记住用户勾选了,则从本地缓存中读取上次登陆的用户名称。
如果记住用户勾选了,则点击登陆提交时,需要将当前用户的名称保存到本地缓存中。
点击皮肤选择框,弹出皮肤选择下拉,但点击界面其他地方时将下拉框隐藏。
点击登陆按钮时请求后台数据,如果登陆成功跳转界面。
如果登陆失败则弹出错误提醒框。
代码存放位置:
直接上代码了:
Login.js的内容:
login.less文件内容:
dva对redux封装了,所以使用起来不需要单独去写所谓的action,以及reducer相关文件。
Login.js直接关联到了src/models/LoginMd.js.
如何关联的:第一步就是新建一个LoginMd.js,并将该models注册到index.js里面
第二步,在Login.js文件开发时,将该文件对应的对象映射进来:
这样就完成了redux相关的各种配置了,确实要简单多了。
src/models/LoginMd.js的内容如下
调用原理:
当在Login.js文件中调用:
loginMd/changePwd中的loginMd对应的是Models的命名空间
loginMd/changePwd中的changePwd对应reducers下的相应方法
到此就完成了登陆界面的开发。该界面里面用到了一个封装组件,皮肤下拉,下节我们来介绍该组件的实现。
具体细节不讲了,有兴趣的可以q我,一起探讨学习
选择皮肤下拉。
功能分析:
点击记住用户名区域,checkbox选中,再点击则checkbox取消选中。
点击皮肤选择框,会显示皮肤下拉。
如果记住用户勾选了,则从本地缓存中读取上次登陆的用户名称。
如果记住用户勾选了,则点击登陆提交时,需要将当前用户的名称保存到本地缓存中。
点击皮肤选择框,弹出皮肤选择下拉,但点击界面其他地方时将下拉框隐藏。
点击登陆按钮时请求后台数据,如果登陆成功跳转界面。
如果登陆失败则弹出错误提醒框。
代码存放位置:
直接上代码了:
Login.js的内容:
import React, { Component } from 'react' // 引入React import { connect,dispatch } from 'react-redux' // 引入connect import topTitleLog from './images/topTitleLog.png'; import sysLogo from './images/sysLogo.png'; import paopao from './images/paopao.png'; import SkinDropCom from '../../components/SkinDropCom'; import 'antd/dist/antd.css'; // or 'antd/dist/antd.less' import '../../assets/css/goingStyle.css'; import './Login.less'; import 'font-awesome/css/font-awesome.min.css'; import {parseBoolean,AssertUtils} from '../../utils/GoingUtils'; import { Link } from 'react-router' import { notification } from 'antd'; class Login extends Component { //构造函数 绑定事件 constructor(...props) { super(...props); [ '_setCurUserName', '_clickLoginBtn', '_selCheckBoxEl', '_setPsw', '_changeCurSkin','_showDropDown' ].forEach(func=> { this[func] = this[func].bind(this); }); } componentWillMount() { } //如果挑战界面 存在错误信息 将错误内容展示出来 componentDidUpdate() { const { dispatch,loginMd}=this.props; if (loginMd.error != null) { notification['error']({ message: '错误信息', description: `系统登陆失败,失败原因:${loginMd.error}`, }); } } //校验用户名 跟 密码是否为空 validateFieldsAndScroll({userName,password}) { if (AssertUtils.isNotEmpty(userName) && AssertUtils.isNotEmpty(password)) { return true; } else { notification['error']({ message: '错误信息', description: `用户名或者密码信息不能为空,请确认!`, }); return false; } } //点击登陆按钮 跳转到首页 _clickLoginBtn() { const { dispatch,loginMd}=this.props; if (this.validateFieldsAndScroll(loginMd)) { //如果是需要记录当前用户名 则将当前用户名称记录到本地缓存中 if (parseBoolean(loginMd.checkVal)) { let newUserName = loginMd.userName; localStorage.removeItem("userName"); localStorage.setItem("userName", newUserName); } dispatch({ type: 'loginMd/loginSys' }); } } //点击记住用户名的checkbox _changeCurSkin(selSkin) { const { dispatch,loginMd}=this.props; dispatch({ type: 'loginMd/changeCurSkin', curSkin: selSkin }); } //点击记住用户名的checkbox _selCheckBoxEl() { const { dispatch,loginMd}=this.props; dispatch({ type: 'loginMd/selCheckBox', checkVal: loginMd.checkVal }); } //显示皮肤选择下拉 _showDropDown(visibilityFlag){ const { dispatch,loginMd}=this.props; dispatch({ type: 'loginMd/showDropDown', visibilityFlag: visibilityFlag }); } //变更密码时 将值放入到状态里管理起来 _setPsw(ev) { const { dispatch,loginMd}=this.props; var newPwd = ev.target.value; dispatch({ type: 'loginMd/changePwd', password: newPwd }); } //变更用户时 将值放入到状态里管理起来 _setCurUserName(ev) { const { dispatch,loginMd}=this.props; var newUserName = ev.target.value; dispatch({ type: 'loginMd/changeUserName', userName: newUserName }); } render() { const {loginMd} =this.props; let userName = loginMd.userName; console.log(this.props.location+"-----------------") if (parseBoolean(loginMd.loginHome)) { window.location.href = "http://localhost:8000/"; } return ( <div> <header> <div className="loginSysImg"> <img src={topTitleLog}/> </div> <div className="loginSysTitle"> <span>欢迎访问ERP系统</span> </div> </header> <div className="pageBody"> <div className="sysImgDiv"> <img src={sysLogo}/> </div> <div className="loginWin"> <div className="goingFlexRow"> <div><input type="text" ref="userName" value={userName} onChange={this._setCurUserName}/></div> <div className="inputImg"><i className="fa fa-user" aria-hidden="true"></i></div> </div> <div className="goingFlexRow"> <div><input type="password" onChange={this._setPsw}/></div> <div className="inputImg"><i className="fa fa-key" aria-hidden="true"></i></div> </div> <div className="goingFlexRow" onClick={(ev)=>{ this._showDropDown(true); ev.stopPropagation(); }}> <div> <input type="text" value={loginMd.currentSkin} onChange={()=>{}}/> </div> <div className="inputImg"><i className="fa fa-caret-down" aria-hidden="true"></i></div> </div> <SkinDropCom skinsList={loginMd.skinsList} visibility={loginMd.visibility} changeCurSkin={this._changeCurSkin} showDropDown={this._showDropDown} width="180px"/> <div className="goingButtonRow"> <div className="labelInfo" onClick={()=>this._selCheckBoxEl()}> <span><input type="checkbox" checked={parseBoolean(loginMd.checkVal)} onChange={()=>{}}/></span> <span><label>记住用户名</label></span> </div> <div className="loginBtnDiv"> <button onClick={()=>this._clickLoginBtn()}>登陆</button> </div> </div> </div> </div> <footer> <div className="sysRight">@copy Right 科技公司版权所有</div> </footer> </div> ) } } // 利用connect将组件与Redux绑定起来 export default connect(({loginMd}) => ({loginMd}))(Login)
login.less文件内容:
@startCol: #FAFAFA; @endCol: #F0F0F0; @navHeight:30px;@baseBorderCol:#CCCCCC; header,footer{ height: @navHeight; width: 100%; background: linear-gradient(@startCol, @endCol); /* 标准的语法 */ display: flex; } header { div.loginSysImg { margin-left: 10px; } div.loginSysTitle { margin-left: 10px; line-height: @navHeight; font-size: 13px; color: #494949; } } div.pageBody { position: absolute; width: 100%; top: 33%; height: 150px; background: linear-gradient(#76CBD4, #2D93A1); /* 标准的语法 */ display: flex; justify-content: center; div.sysImgDiv { position: relative; top: -48px; left: -10px; } div.loginWin { padding: 10px 10px; width: 200px; div.goingFlexRow { width: 100%; margin-top: 6px; display: flex; } div.goingButtonRow { display: flex; justify-content: space-between; margin-top: 10px; .labelInfo { position: relative; top: 5px; label { position: relative; top: -3px; left: 5px; color: #fff; display: inline-block; } } .loginBtnDiv { cursor: pointer; position: relative; button { width: 70px; height: 25px; line-height: 25px; cursor: pointer; &:hover { background: linear-gradient(#DDDDDD, #C9C9C9); /* 标准的语法 */ } } } } } } footer { position: fixed; bottom: 0px; border-top: 1px solid @baseBorderCol; .sysRight { line-height:@navHeight; margin-left: 10px; font-size: 13px; } } .inputImg { position: relative; left: -16px; top: 3px; } .inputCom{ height: 23px; width: 180px; border: 1px solid @baseBorderCol; border-radius: 3px; } input[type="text"] { .inputCom; } input[type="password"] { .inputCom; } input[type="checkbox"] { height: 15px; width: 15px; }
dva对redux封装了,所以使用起来不需要单独去写所谓的action,以及reducer相关文件。
Login.js直接关联到了src/models/LoginMd.js.
如何关联的:第一步就是新建一个LoginMd.js,并将该models注册到index.js里面
app.model(require('./models/LoginMd'));
第二步,在Login.js文件开发时,将该文件对应的对象映射进来:
// 利用connect将组件与Redux绑定起来 export default connect(({loginMd}) => ({loginMd}))(Login)
这样就完成了redux相关的各种配置了,确实要简单多了。
src/models/LoginMd.js的内容如下
import {loginSv, findCurrentUser, logout} from '../services/LoginSv' import {parse} from 'qs' import {parseBoolean,AssertUtils} from '../utils/GoingUtils'; export default { namespace: 'loginMd', state: { //从本地缓存中读取是否选中的状态值 checkVal:((curCheckVal=false)=>{ return curCheckVal; })(localStorage.getItem("checkVal")), userName:(()=>{ //如果记住用户名是true 则本地缓存中获取用户信息 if(parseBoolean(localStorage.getItem("checkVal"))){ return localStorage.getItem("userName"); }else{ return ''; } })(), visibility:"hidden", currentSkin:((currentSkin='蓝色金典')=>{ return currentSkin; })(localStorage.getItem("currentSkin")||'蓝色金典'), //皮肤下拉 skinsList: [ {text: '蓝色金典',itemId:'blue'}, {text: '浅色简约',itemId:'apply'}, {text: '简约时尚',itemId:'shisha'} ] }, subscriptions: { setup({ dispatch, history }) { // eslint-disable-line }, }, effects: { *loginSys({ payload }, { call, put }) { const record = yield call(loginSv, parse(payload)); if (record.code) { yield put({ type: 'loginSuccess', payload: { user: record.data }}) } else { yield put({ type: 'loginFail' }) } }, }, reducers: { selCheckBox(state, action) { //讲checkVal的值保存到本地缓存中 localStorage.removeItem("checkVal"); localStorage.setItem("checkVal",!parseBoolean(action.checkVal)); return { ...state, checkVal:!parseBoolean(action.checkVal)}; }, changeUserName(state, action) { //用户名输入的值变更 return { ...state, userName:action.userName}; }, changePwd(state, action) { //密码值的变更 return { ...state, password:action.password}; }, showDropDown(state, action) { //皮肤下拉的显示与隐藏 return { ...state, visibility:parseBoolean(action.visibilityFlag)?"visible":"hidden"}; }, changeCurSkin(state, action) { //选择相应的皮肤选项 localStorage.removeItem("currentSkin"); localStorage.setItem("currentSkin",action.curSkin); return { ...state, visibility:"hidden",currentSkin:action.curSkin}; }, loginSuccess (state, action) { //登陆成功 return { ...state, ...action.payload, loginHome: true, loginButtonLoading: false } }, loginFail (state) { return { ...state, login: false, error:'用户名或者密码不正确', loginButtonLoading: false } }, }, };
调用原理:
当在Login.js文件中调用:
dispatch({ type: 'loginMd/changePwd', password: newPwd });
loginMd/changePwd中的loginMd对应的是Models的命名空间
namespace: 'loginMd',
loginMd/changePwd中的changePwd对应reducers下的相应方法
changePwd(state, action) { //密码值的变更 return { ...state, password:action.password}; },
到此就完成了登陆界面的开发。该界面里面用到了一个封装组件,皮肤下拉,下节我们来介绍该组件的实现。
具体细节不讲了,有兴趣的可以q我,一起探讨学习
相关文章推荐
- react项目实战(权限模块开发六)semantic-ui-react 加入到开发环境中
- react项目实战(权限模块开发八)js文件分开打包
- react项目实战(权限模块开发五) 系统首页开发
- react项目实战(权限模块开发二) 项目配置修改
- react项目实战(权限模块开发四) SkinDropDown插件开发
- react项目实战(权限模块开发七)通过ajax技术获取数据
- react项目实战(权限模块开发九)dva的table控件使用
- react项目实战(权限模块开发一) 配置路由
- 从一个实战项目来看一下React Native开发的几个关键技术点
- 2017.7.1 慕课网-Java从零打造企业级电商项目实战:3 category模块设计与开发
- React Native商城项目实战08 - 设置“More”界面cell
- 从零开发一个完整的Android项目(六)——欢迎(登陆)界面
- 2017.7.1 慕课网-Java从零打造企业级电商项目实战:2用户模块设计与开发
- React新闻头条项目实战React.js入门基础与案例开发
- 【小松教你手游开发】【unity系统模块开发】Unity动画系统项目实战
- Maven Web项目Servlet开发之登陆界面
- 电商项目(二十五)用户模块开发(登陆功能开发)
- .NET快速信息化系统开发框架 V3.2 -> WinForm“组织机构管理”界面组织机构权限管理采用新的界面,操作权限按模块进行展示
- 2017.7.1 慕课网-Java从零打造企业级电商项目实战:3 category模块设计与开发
- 从一个实战项目来看一下React Native开发的几个关键技术点