七.编写Login页面组件以及button样式类
1.scss中编写common.css,样式初始化
html{
font-size: 14px;
background-color: #f3f5f7;
color: #333;
}
body{
margin:0;
}
ul{
padding: 0;
margin: 0;
list-style: none;
}
a{
text-decoration: none;
color: #333;
}
input,
button{
outline: none;
border:none;
box-sizing: border-box;
border-radius: 3px;
}
h1,h2,h3,h4,h5,h6,p{
margin:0;
font-weight: normal;
}
div{
box-sizing: border-box;
}
i{
font-style: normal;
}
.clearfix::after{
content: "";
display: block;
clear:both
}
2.iconfont文件引入
3.index.js引入
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import * as serviceWorker from './serviceWorker';
import './assets/scss/common.css';
import './assets/scss/iconfont.css';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
4.compenents中新建login文件夹,在其建立Form和logo文件夹
,index.js&index.scss文件
import React, { Component } from 'react'
import './index.scss'
export default class Login extends Component {
render() {
return (
<div className="login-container">
</div>
)
}
}
}
}
login-container{
position: fixed;
top: 50%;
left: 50%;
width: 600px;
height: 250px;
margin: -125px 0 0 -300px;
background-color: #fff;
box-shadow: 1px 3px 5px #999;
border-radius: 20px;
}
5.pages中login.js下引用组件
import React, { Component } from 'react'
import Login from "../components/Login"
export default class login extends Component {
constructor(props){
super(props)
this.state={}
}
render() {
return (
<div className="container">
<Login></Login>
</div>
)
}
}
6.在components中的Login文件夹下的logo文件夹下建立index.js和index.scss
import React, { Component } from 'react'
import './index.scss'
export default class Logo extends Component {
render() {
return (
<div className="logo-wrapper">
</div>
)
}
}
.logo-wrapper{
width: 180px;
height: 180px;
margin: 35px 0 0 50px;
background: url('../../../assets/img/logo.png') no-repeat;
background-size: 180px 180px;
}
7.父组件index.js中引用
import React, { Component } from 'react'
import Logo from './Logo'
import './index.scss'
export default class Login extends Component {
render() {
return (
<div className="login-container">
<Logo/>
</div>
)
}
}
8.from文件夹中新建LoginForm和title文件夹,与index.js和index.scss
import React, { Component } from 'react'
import './index.scss'
export default class Form extends Component {
render() {
return (
<div className="form-wrapper">
</div>
)
}
}
.form-wrapper{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 30px 15px 15px 250px;
}
9.外层的login.js引入
import React, { Component } from 'react'
import Logo from './Logo'
import Form from './Form'
import './index.scss'
export default class Login extends Component {
render() {
return (
<div className="login-container">
<Logo/>
<Form/>
</div>
)
}
}
10.title文件夹中新建index.js和index.scss
import React, { Component } from 'react'
import './index.scss'
export default class Title extends Component {
render() {
return (
<h1 className="login-title">海儿兄弟官方网站管理后台</h1>
)
}
}
.login-title{
font-size: 23px;
text-align: center;
}
11.在loginform中新建index.js和index.scss
import React, { Component } from 'react'
import './index.scss'
export default class LoginForm extends Component {
render() {
return (
<div className="login-form-wrapper">
<div className="input-box">
<i className="iconfont icon-user"></i>
<input type="text" className="login-input" placeholder="用户名"></input>
</div>
<div className="input-box">
<i className="iconfont icon-lock"></i>
<input type="password" className="login-input" placeholder="密码"></input>
</div>
<div className="input-box">
<button className="btn btn-primary">登录后台</button>
</div>
</div>
)
}
}
.btn{
width: 100%;
height: 100%;
border-radius: 3px;
color:#fff;
font-size: 14px;
&.btn-primary{
background-color: #337ab7;
border-color: #2e6da4;
&:hover{
background-color: #286090;
border-color: #204d74;
}
}
&.btn-success{
background-color: #5cb85c;
border-color: #4cae4c;
&:hover{
background-color: #449d44;
border-color: #398439;
}
}
&.btn-info{
background-color: #5bc0de;
border-color: #46b8da;
&:hover{
background-color: #31b0d5;
border-color: #269abc;
}
}
&.btn-warning{
background-color: #f0ad4e;
border-color: #eea236;
&:hover{
background-color: #ec971f;
border-color: #d58512;
}
}
&.btn-danger{
background-color: #d9534f;
border-color: #de3f3a;
&:hover{
background-color: #c9302c;
border-color: #ac2925;
}
}
}
import './assets/scss/button.scss'
.login-form-wrapper{
widows: 100%;
.input-box{
position: relative;
width: 250px;
height: 35px;
margin: 18px auto 0;
.iconfont{
position: absolute;
top:7px;
left: 10px;
font-size: 18px;
color:#999;
}
.login-input{
width: 100%;
height: 100%;
border: 1px solid #ddd;
text-indent: 35px;
font-size: 14px;
}
}
}
12.form中引入这两个组件
import React, { Component } from 'react'
import './index.scss'
import Title from './Title'
import LoginForm from './LoginForm'
export default class Form extends Component {
render() {
return (
<div className="form-wrapper">
<Title/>
<LoginForm/>
</div>
)
}
}
八.axios请求数据以及Koa2跨域请求配置
1.安装axios
npm i axios -S
在组件的login文件夹下的index.js中
import React, { Component } from 'react'
import axios from 'axios'
import Logo from './Logo'
import Form from './Form'
import './index.scss'
export default class Login extends Component {
getCourseData(){
axios('http://localhost:3000/get_courses')
.then((res)=>{
console.log(res)
})
}
componentDidMount()
{
this.getCourseData();
}
render() {
return (
<div className="login-container">
<Logo/>
<Form/>
</div>
)
}
}
2.测试连接前后端
npm i koa2-cors -S
const cors = require('koa2-cors');
app.use(cors({
origin:function(ctx){
return 'http://localhost:3001'
}
}))
const {getCourses} = require('../service/course')
async getCourseData(ctx,next){
const data = await getCourses();
ctx.body = data;
}
在service中的course.js中写getcourseData
async getCourses(){
return await CourseModel.findAll()
}
3.在route的index.js中配置路由
const router = require('koa-router')(),
indexController = require('../controller/index')
router.get('/',indexController.index )
router.get('/get_courses',indexController.getCourseData)
module.exports = router
4.config.js中配置
{isPard} = require('./env_config');
corsOrigin:isPard ? 'xxx':'http://localhost:3001'
5.app.js中配置
const {sessionInfo,cookieInfo,redisInfo,corsOrigin} = require('./config/config')
app.use(cors({
origin:function(ctx){
return corsOrigin
}
}))
九.编写登录接口以及抽离返回信息集合
module.exports={
LOGIN:{
INVALID_USERNAME_LENGTH:{
error_code:10001,
error_msg:'Invalid username length'
},
INVALID_PASSWORD_LENGTH:{
error_code:10002,
error_msg:'Invalid password length'
},
USERNAME_NOT_EXIST:{
error_code:10003,
error_msg:'Username is not exist in database'
},
PASSWORD_ERROR:{
error_code:10004,
error_msg:'Password doesn\'t matched with the username'
},
INVALID_OPERATION:{
error_code:10005,
error_msg:'Invalid operation'
},
SUCCESS:{
error_code:0,
error_msg:'Login is ok'
}
}
}
2.lib下的util.js
function trimSpace(str){
return str.replace(/\s+/g,'')
}
function returnInfo(errorInfo,data){
if(data){
errorInfo.data = data
}
return errorInfo
}
module.exports = {
startProcess, qiniuUpload,makeCrypto,trimSpace,returnInfo
}
3.service中的admin.js
async login(userInfo){
const {username,password} = userInfo;
const usernameExist = await AdminModel.findOne({
where:{username}
})
if(!usernameExist){
return 10003
}
const dbPassword = usernameExist.get('password');
if(password != dbPassword){
return 10004
}
return 0;
}
4.在控制器中的的Admin.js中编写登录接口
const {adminInfo} = require('../config/config'),
{addAdmin, login} = require('../service/admin'),
{makeCrypto,trimSpace,returnInfo} = require('../lib/util'),
{LOGIN} = require('../config/err_config')
class Admin {
async createAdmin(){
adminInfo.password = makeCrypto(adminInfo.password)
const result = await addAdmin(adminInfo);
if(result){
console.log(0);
}else{
console.log(1);
}
}
async loginAction(ctx,next){
const {username,password} = ctx.request.body;
if(!username||!password){
ctx.body = returnInfo(LOGIN.INVALID_OPERATION)
return
}
if(trimSpace(username).length<=0){
ctx.body = returnInfo(LOGIN.INVALID_USERNAME_LENGTH);
return
}
if(trimSpace(password).length<=0){
ctx.body = returnInfo(LOGIN.INVALID_PASSWORD_LENGTH)
}
const userInfo = {
username:trimSpace(username),
password:makeCrypto(trimSpace(password))
}
const result = await login(userInfo);
if(result === 10003){
ctx.body = returnInfo(LOGIN.USERNAME_NOT_EXIST)
return
}
if(result === 10004){
ctx.body = returnInfo(LOGIN.PASSWORD_ERROR)
return
}
return ctx.body = returnInfo(LOGIN.SUCCESS)
}
}
module.exports = new Admin();
5.admin.js中添加路由
const router = require('koa-router')(),
adminController = require('../controller/admin')
router.prefix('/admin')
router.get('/create_admin',adminController.createAdmin)
router.post('/login_action',adminController.loginAction)
module.exports = router;