博客项目之前端开发—注册功能实现

1、前端注册功能实现

  在service/user.js中增加reg注册函数     

 1 import axios from "axios"
 2 import { observable } from "mobx";
 3 import store from 'store'
 4 
 5 // 过期插件
 6 store.addPlugin(require('store/plugins/expire'))
 7 
 8 class UserService {
 9     // 定义被观察对象
10     @observable loggedin = false
11 
12     //登录
13     login (email, password) {
14         //TODO
15         console.log('----------------')
16         console.log(email)
17         console.log(password)
18         console.log('----------------')
19 
20         axios.post('/api/user/login', {
21             email:email,
22             password:password
23             })// 成功执行
24             // 普通函数,用箭头处理this问题
25             .then((response) => {
26                 console.log(1,response);
27                 console.log(2,response.data)
28                 const {token, user} = response.data
29                 console.log(3,token)
30                 store.set('token',token, (new Date()).getTime() + (8 * 3600 * 1000))
31                 console.log(4,user)
32                 //成功后,状态改变
33                 this.loggedin = true
34 
35             })//错误就不执行
36             .catch( (error) => {
37                 console.log(7,error);
38                 this.loggedin = false;
39             });
40     }
41 
42     // 注册
43     reg (name, email, password) {
44         //TODO
45         console.log('-------***---------')
46         console.log(email)
47         console.log(password)
48         console.log('-------***---------')
49 
50         axios.post('/api/user/reg', {
51             email:email,
52             password:password,
53             name:name
54             })// dev server 会代理
55             // 普通函数,用箭头处理this问题
56             .then( response => {
57                 console.log(1,response);
58                 console.log(2,response.data)
59                 console.log(3,response.status)
60                 const {token, user} = response.data
61                 console.log(4,token)
62                 // 存储token
63                 store.set('token',token, (new Date()).getTime() + (8 * 3600 * 1000))
64                 console.log(5,user)
65                 //成功后,状态改变
66                 console.log('==================')
67                 this.loggedin = true
68                 console.log('==================')
69 
70             })//错误就不执行
71             .catch(error => {
72                 console.log(6,error);
73                 this.loggedin = false;
74             });
75     }
76 }
77 
78 
79 
80 //全局变量
81 const userService = new UserService()
82 
83 export {userService}

         《===等价===》

     测试:

     

     component/reg.js 组件:

 1 import React from 'react'
 2 import{Link, Redirect} from 'react-router-dom'
 3 import '../css/login.css'
 4 import {userService as service} from '../service/user';
 5 import { observer } from 'mobx-react';
 6 
 7 
 8 
 9 export default class Reg extends React.Component{
10     render(){
11         return <_Reg service={service} />;
12     }
13 }
14 // 观察者
15 @observer
16 class _Reg extends React.Component{
17     validatePwd(pwd1, pwd2) {
18         return pwd1.value == pwd2.value  //确保两次输入的密码一致,下面没有代码,可以自己添加
19     }        
20 
21     handleClick(event) {
22         event.preventDefault()
23         console.log(typeof(event.target.form),'=========')
24         const [name, email, password, confirm] = event.target.form;
25         console.log(this.validatePwd(password, confirm),'===========')
26         this.props.service.reg(name.value, email.value, password.value);
27 
28     }
29     
30     render(){
31         if (this.props.service.loggedin) {
32             return <Redirect to="/" />
33         }
34         return(
35             <div className="login-page">
36             <div className="form">
37             <form className="register-form">
38                 <input type="text" placeholder="姓名"/>
39                 <input type="text" placeholder="邮箱"/>
40                 <input type="password" placeholder="密码"/>
41                 <input type="password" placeholder="确认密码"/>
42                 <button onClick={this.handleClick.bind(this)}>注册</button>
43                 <p className="message">已经注册? <Link to="/login">登录</Link></p>
44             </form>
45             </div>
46       </div>
47         )
48     }
49 }
 1 # 注册(业务) insert
 2 def reg(request:HttpRequest):
 3     try:
 4         play = simplejson.loads(request.body)
 5         # print(play, type(play),'========================')
 6         email = play["email"]
 7         a = User.objects.filter(email=email)
 8         # print(a.query) # 查看查询语句
 9         if a.first():# 懒惰,只要用,就会查
10             return HttpResponseBadRequest('用户名存在')
11         print('--------------------------------------')
12         name = play["name"]
13         # 这两步可以合起来,减少计算
14         password = play["password"]
15         print(password)
16         password = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
17         # ORM 操作
18         user = User()
19         user.email = email
20         user.name = name
21         user.password = password
22 
23         try: # 这个try可以去掉,不要把e法到浏览器端,
24             # 这个try里可以做些特殊处理;
25             user.save() # commit提交
26             # 如果正常,返回json数据
27             token = gen_token(user.id)
28             res = JsonResponse({
29                 'user': {
30                     "user_id": user.id,
31                     "name": user.name,
32                     "email": user.email
33                 },
34                 'token': token
35             })
36             res.set_cookie('Jwt', token)  # set cookie
37             return res
38         except jwt.ExpiredSignatureError as e:
39             print(e)
40             return HttpResponseBadRequest("jwt 过期了")
41         except Exception as e:
42             print(e)
43             # return HttpResponseBadRequest("参数错误")
44             raise # 直接往外抛,外面的接住。
45     except Exception as e: # 有任何异常返回。
46         print(e,'==')
47         return HttpResponseBadRequest("参数错误") # 这里返回实例,这不是异常类,继承自httpresponse
后台user/reg.py

  注意:

    所有的业务操作都是对一个service实例的操作,不能说,注册使用一个service实例,登录使用一个service实例,这样两者没有任何关系

    所以直接从service/user.js 中导出,为每个业务使用

    

    本项目是:只要注册成功,就不需要登录了,直接登录成功,所以后台直接返回token  

2、Ant Design

  Ant Design 蚂蚁金服开源的 React UI 库

  官网:https://ant.design/index-cn

  官方文档:https://ant.design/docs/react/introduce-cn

  安装: $npm  install antd    $ yarn add antd

  使用:

    

3、网页中信息显示  

   网页开发中,不管操作成功与否,有很多信息提示, 目前信息都是控制台输出的,用户看不到,使用Antd的message组件显示友好信息提示

  在service/user.js 中增加一个被观察对象

  

 1 import axios from "axios"
 2 import { observable } from "mobx";
 3 import store from 'store'
 4 
 5 
 6 // 过期插件
 7 store.addPlugin(require('store/plugins/expire'))
 8 
 9 class UserService {
10     // 定义被观察对象
11     @observable loggedin = false
12     @observable errMsg = '' // 登录错误信息
13 
14     //登录
15     login (email, password) {
16         //TODO
17         console.log('----------------')
18         console.log(email)
19         console.log(password)
20         console.log('----------------')
21 
22         axios.post('/api/user/login', {
23             email:email,
24             password:password
25             })// 成功执行
26             // 普通函数,用箭头处理this问题
27             .then((response) => {
28                 console.log(1,response);
29                 console.log(2,response.data)
30                 const {token, user} = response.data
31                 console.log(3,token)
32                 store.set('token',token, (new Date()).getTime() + (8 * 3600 * 1000))
33                 console.log(4,user)
34                 //成功后,状态改变
35                 this.loggedin = true
36                 this.errMsg = ''
37 
38             })//错误就不执行
39             .catch( (error) => {
40                 console.log(7,error);
41                 this.loggedin = false;
42                 this.errMsg = '登录名或密码错误'
43             });
44     }
45 
46     // 注册
47     reg (name, email, password) {
48         //TODO
49         console.log('-------***---------')
50         console.log(email)
51         console.log(password)
52         console.log('-------***---------')
53 
54         axios.post('/api/user/reg', {
55             email,
56             password,
57             name
58             })// dev server 会代理
59             // 普通函数,用箭头处理this问题
60             .then( response => {
61                 console.log(1,response);
62                 console.log(2,response.data)
63                 console.log(3,response.status)
64                 const {token, user} = response.data
65                 console.log(4,token)
66                 // 存储token
67                 store.set('token',token, (new Date()).getTime() + (8 * 3600 * 1000))
68                 console.log(5,user)
69                 //成功后,状态改变
70                 console.log('==================')
71                 this.loggedin = true
72                 this.errMsg = '  '
73                 console.log('==================')
74 
75             })//错误就不执行
76             .catch(error => {
77                 console.log(6,error);
78                 this.loggedin = false;
79                 this.errMsg = '注册失败'
80 
81             });
82     }
83 }
84 
85 
86 
87 //全局变量
88 const userService = new UserService()
89 
90 export {userService}

    component/login.js组件,增加Antd的message组件

 1 import React from 'react';
 2 import {Link,Redirect} from 'react-router-dom';
 3 import '../css/login.css';
 4 import {userService as service} from '../service/user';
 5 import { observer } from 'mobx-react';
 6 import { message } from  'antd'
 7 import 'antd/lib/message/style'
 8 
 9 
10 
11 
12 export default class Login extends React.Component{
13     render(){
14         return <_Login service={service} />;
15     }
16 }
17 // 观察者
18 @observer
19 class _Login extends React.Component {
20     handleClick(event) {
21         event.preventDefault();
22         const [email, password] = event.target.form
23         this.props.service.login(email.value, password.value)// 获取表单的值
24     }
25 
26 
27     render(){
28         console.log('======================')
29         // 观察者发现改变了,在这里只要用一次,即便是打印,就会通知render
30         // 没有改变,则不会被调用loggedin
31         console.log(this.props.service.loggedin)
32         // 登录成功之后,就不会往下走了,直接return,并跳转
33         if (this.props.service.loggedin) return <Redirect to="/" />
34         //import { message } from  'antd'
35         // 官网提供的函数:显示3秒信息,之后,置空
36         if (this.props.service.errMsg) {// 如果注册失败,才会进来
37             //js中 [] {} 等效true
38             message.info(this.props.service.errMsg, 3, 
39             () => this.props.service.errMsg = '')
40         }
41         
42         return(
43             <div className="login-page">
44                 <div className="form">
45                 <form className="login-form">
46                 <input type="text" placeholder="邮箱"/>
47                 <input type="password" placeholder="密码"/>
48                 <button onClick={this.handleClick.bind(this)}>登录</button>
49                 <p className="message">未注册? <a href="#">立即注册</a></p>
50                 {/* <span>{this.props.service.errMsg}</span> */}
51                 </form>
52                 </div>
53             </div>
54         )
55     }
56 }

     结果:

      

    上面的代码执行到用户登录失败的时候,浏览器控制台会抛出 一个警告:

    

    

    解决办法:

      将消息的清除代码移动到 componentDidUpdat中(render结束后执行 消息提示)

 1 import React from 'react';
 2 import {Link,Redirect} from 'react-router-dom';
 3 import '../css/login.css';
 4 import {userService as service} from '../service/user';
 5 import { observer } from 'mobx-react';
 6 import { message } from  'antd'
 7 import 'antd/lib/message/style'
 8 
 9 
10 
11 
12 export default class Login extends React.Component{
13     render(){
14         return <_Login service={service} />;
15     }
16 }
17 // 观察者
18 @observer
19 class _Login extends React.Component {
20     handleClick(event) {
21         event.preventDefault();
22         const [email, password] = event.target.form
23         this.props.service.login(email.value, password.value)// 获取表单的值
24     }
25 
26 
27     render(){
28         console.log('======================')
29         // 观察者发现改变了,在这里只要用一次,即便是打印,就会通知render
30         // 没有改变,则不会被调用loggedin
31         console.log(this.props.service.loggedin)
32         // 登录成功之后,就不会往下走了,直接return,并跳转
33         if (this.props.service.loggedin) return <Redirect to="/" />
34 
35         let em =  this.props.service.errMsg; // 引用这个值,留作观察,否则不知道时候改了没
36         
37         return(
38             <div className="login-page">
39                 <div className="form">
40                 <form className="login-form">
41                 <input type="text" placeholder="邮箱"/>
42                 <input type="password" placeholder="密码"/>
43                 <button onClick={this.handleClick.bind(this)}>登录</button>
44                 <p className="message">未注册? <a href="#">立即注册</a></p>
45                 {/* <span>{this.props.service.errMsg}</span> */}
46                 </form>
47                 </div>
48             </div>
49         )
50     }
51     componentDidUpdate(prevProps, prevState) { //渲染后,显示消息组件
52         //这里的prevProps和下面的this.props是同一个值,因为service这个属性没有改变
53         //一直是user。js中导出的service
54         //import { message } from  'antd'
55         // 官网提供的函数:显示3秒信息,之后,置空
56         if (prevProps.service.errMsg) {// 如果注册失败,才会进来
57             //js中 [] {} 等效true
58             message.info(prevProps.service.errMsg, 3, 
59             () => prevProps.service.errMsg = '')
60         }
61     }
62 }

  component/reg.js组件同样增加message组件

 1 import React from 'react'
 2 import{Link, Redirect} from 'react-router-dom'
 3 import '../css/login.css'
 4 import {userService as service} from '../service/user';
 5 import { observer } from 'mobx-react';
 6 import { message } from  'antd'
 7 import 'antd/lib/message/style'
 8 import {inject} from '../utils'
 9 
10 
11 
12 // 观察者
13 @inject({service})
14 @observer
15 class _Reg extends React.Component{
16     validatePwd(pwd1, pwd2) {
17         return pwd1.value == pwd2.value
18     }
19     validateEma(email) {
20         // email校验
21     }        
22 
23     handleClick(event) {
24         event.preventDefault()
25         console.log(typeof(event.target.form),'=========')
26         const [name, email, password, confirm] = event.target.form;
27         if (this.validatePwd(password, confirm) ){
28             this.props.service.reg(name.value, email.value, password.value);  
29                     
30         }
31         else {
32             console.log('两次密码不同')
33             this.props.service.reg(name.value, email.value, password.value,false);   
34         }
35 
36 
37     }
38     
39     render(){
40         if (this.props.service.loggedin) {
41             return <Redirect to="/" />
42         }
43         let em =  this.props.service.errMsg; // 引用这个值,留作观察,否则不知道时候改了没
44 
45         return(
46             <div className="login-page">
47             <div className="form">
48             <form className="register-form">
49                 <input type="text" placeholder="姓名"/>
50                 <input type="text" placeholder="邮箱"/>
51                 <input type="password" placeholder="密码"/>
52                 <input type="password" placeholder="确认密码"/>
53                 <button onClick={this.handleClick.bind(this)}>注册</button>
54                 <p className="message">已经注册? <Link to="/login">登录</Link></p>
55             </form>
56             </div>
57       </div>
58         )
59     }
60     componentDidUpdate(prevProps, prevState) { //渲染后,显示消息组件
61         //这里的prevProps和下面的this.props是同一个值,因为service这个属性没有改变
62         //一直是user。js中导出的service
63         //import { message } from  'antd'
64         // 官网提供的函数:显示3秒信息,之后,置空
65         if (prevProps.service.errMsg) {// 如果注册失败,才会进来
66             //js中 [] {} 等效true
67             message.info(prevProps.service.errMsg, 3, 
68             () => prevProps.service.errMsg = '')
69         }
70     }
71 }

 

4、高阶组件装饰器

  装饰器函数的整个过程演变如下:

 1 export default class Login extends React.Component{
 2     render(){
 3         return <_Login service={service} />;
 4     }
 5 }
 6 
 7 class Login extends React.Component{
 8     render(){
 9         return <_Login service={service} />;
10     }
11 }
12 // 匿名 组件
13 const Login = class extends React.Component {
14     render(){
15         return <_Login service={service} />;
16     }
17 }
18 // 提参数
19 function inject (){
20     return Login
21 }
22 
23 function inject() {
24     return class extends React.Component {
25         render(){
26             return <_Login service={service} />;
27         }
28     }
29 }
30 
31 function inject(x,Comp) {
32     return class extends React.Component {
33         render(){
34             return <Comp service={x} />;
35         }
36     }
37 }
38 
39 //柯里化
40 function inject(x) {
41     function wrapper (Comp) {
42         return class extends React.Component {
43             render(){
44                 return <Comp service={x} />;
45             }
46         }
47     }
48     return wrapper
49 }
50 
51 
52 
53 function inject(obj) {
54     function wrapper (Comp) {
55         return class extends React.Component {
56             render(){
57                 return <Comp {...obj} />
58             }
59         }
60     }
61     return wrapper
62 }
63 
64 function inject(obj) {
65     return  wrapper (Comp) {
66         return class extends React.Component {
67             render(){
68                 return <Comp {...obj} />
69             }
70         }
71     }
72 }
73 
74 const inject = obj =>  Comp => {
75         return class extends React.Component {
76             render(){
77                 return <Comp {...obj} />
78             }
79         }
80     }
81 //等价为一个无状态组件
82 const inject = obj =>  Comp => {
83     return function (props) {
84             return <Comp {...obj} />    
85     }
86 }
87 
88 
89 const inject = obj =>  Comp => {
90     props => <Comp {...obj} />;
91 }
92 
93 const inject = obj =>  Comp => props => <Comp {...obj} />;
94 const inject = obj =>  Comp => props => <Comp {...obj} {...props} />;

    新建一个工具文件 src/utils.js  放入以下内容:

1 import React from 'react'
2 
3 const inject = obj =>  Comp => props => <Comp {...obj} {...props} />;
4 
5 
6 export {inject}

    将登录,注册组件装饰一下:

    具体代码:Mobx的observer 装饰器要求,所以注意装饰的顺序

 1 import React from 'react';
 2 import {Link,Redirect} from 'react-router-dom';
 3 import '../css/login.css';
 4 import {userService as service} from '../service/user';
 5 import { observer } from 'mobx-react';
 6 import { message } from  'antd'
 7 import 'antd/lib/message/style'
 8 import {inject} from '../utils'
 9 
10 
11 @inject({service})
12 @observer//官方推荐,贴近类
13 export default class Login extends React.Component {
14     handleClick(event) {
15         event.preventDefault();
16         const [email, password] = event.target.form
17         this.props.service.login(email.value, password.value)// 获取表单的值
18     }
19 
20 
21     render(){
22         console.log('======================')
23         // 观察者发现改变了,在这里只要用一次,即便是打印,就会通知render
24         // 没有改变,则不会被调用loggedin
25         console.log(this.props.service.loggedin)
26         // 登录成功之后,就不会往下走了,直接return,并跳转
27         if (this.props.service.loggedin) return <Redirect to="/" />
28 
29         let em =  this.props.service.errMsg; // 引用这个值,留作观察,否则不知道时候改了没
30         
31         return(
32             <div className="login-page">
33                 <div className="form">
34                 <form className="login-form">
35                 <input type="text" placeholder="邮箱"/>
36                 <input type="password" placeholder="密码"/>
37                 <button onClick={this.handleClick.bind(this)}>登录</button>
38                 <p className="message">未注册? <a href="#">立即注册</a></p>
39                 {/* <span>{this.props.service.errMsg}</span> */}
40                 </form>
41                 </div>
42             </div>
43         )
44     }
45     componentDidUpdate(prevProps, prevState) { //渲染后,显示消息组件
46         //这里的prevProps和下面的this.props是同一个值,因为service这个属性没有改变
47         //一直是user。js中导出的service
48         //import { message } from  'antd'
49         // 官网提供的函数:显示3秒信息,之后,置空
50         if (prevProps.service.errMsg) {// 如果注册失败,才会进来
51             //js中 [] {} 等效true
52             message.info(prevProps.service.errMsg, 3, 
53             () => prevProps.service.errMsg = '')
54         }
55     }
56 }
login.js
 1 import React from 'react'
 2 import{Link, Redirect} from 'react-router-dom'
 3 import '../css/login.css'
 4 import {userService as service} from '../service/user';
 5 import { observer } from 'mobx-react';
 6 import { message } from  'antd'
 7 import 'antd/lib/message/style'
 8 import {inject} from '../utils'
 9 
10 
11 
12 // 观察者
13 @inject({service})
14 @observer
15 class _Reg extends React.Component{
16     validatePwd(pwd1, pwd2) {
17         return pwd1.value == pwd2.value
18     }
19     validateEma(email) {
20         // email校验
21     }        
22 
23     handleClick(event) {
24         event.preventDefault()
25         console.log(typeof(event.target.form),'=========')
26         const [name, email, password, confirm] = event.target.form;
27         if (this.validatePwd(password, confirm) ){
28             this.props.service.reg(name.value, email.value, password.value);  
29                     
30         }
31         else {
32             console.log('两次密码不同')
33             this.props.service.reg(name.value, email.value, password.value,false);   
34         }
35 
36 
37     }
38     
39     render(){
40         if (this.props.service.loggedin) {
41             return <Redirect to="/" />
42         }
43         let em =  this.props.service.errMsg; // 引用这个值,留作观察,否则不知道时候改了没
44 
45         return(
46             <div className="login-page">
47             <div className="form">
48             <form className="register-form">
49                 <input type="text" placeholder="姓名"/>
50                 <input type="text" placeholder="邮箱"/>
51                 <input type="password" placeholder="密码"/>
52                 <input type="password" placeholder="确认密码"/>
53                 <button onClick={this.handleClick.bind(this)}>注册</button>
54                 <p className="message">已经注册? <Link to="/login">登录</Link></p>
55             </form>
56             </div>
57       </div>
58         )
59     }
60     componentDidUpdate(prevProps, prevState) { //渲染后,显示消息组件
61         //这里的prevProps和下面的this.props是同一个值,因为service这个属性没有改变
62         //一直是user。js中导出的service
63         //import { message } from  'antd'
64         // 官网提供的函数:显示3秒信息,之后,置空
65         if (prevProps.service.errMsg) {// 如果注册失败,才会进来
66             //js中 [] {} 等效true
67             message.info(prevProps.service.errMsg, 3, 
68             () => prevProps.service.errMsg = '')
69         }
70     }
71 }
reg.js

     

@inject({service}) // Reg=inject({service})(Reg)  props是Login组件自己的 属性props

  

猜你喜欢

转载自www.cnblogs.com/JerryZao/p/10051244.html