您的位置:首页 > Web前端 > Node.js

ant design+node.js+mongoose实现一个简单的注册登录功能

2017-05-17 21:32 1106 查看
利用antd esign+node.js+mongoose实现一个简单的登录注册功能demo

前端使用ant design,后台服务采用node.js和mongoose操作mongodb实现对输入的信息进行录入和查询

demo整体结构:



src文件夹中存放相应的react代码,其中index.js是入口文件

myserver.js中是后台服务代码,用来操作http请求和mongoose

loginform.js:

/**
* Created by lyy on 2017/4/12.
*/

import React from 'react'
import {Form, Icon, Input, Button, Modal} from 'antd';
const FormItem = Form.Item;

function hasErrors(fieldsError) {
return Object.keys(fieldsError).some(field => fieldsError[field]);
}

class HorizontalLoginForm extends React.Component {

componentDidMount() {
// To disabled submit button at the beginning.
this.props.form.validateFields();
};

handleSubmit = (e) => {
e.preventDefault();

this.props.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
fetch('http://localhost:3000/post/api/1.0/query',
{
method: "POST",
body: JSON.stringify(values),
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
}
});
}
});
};

state = {visible: false};
showModal = () => {
this.setState({
visible: true,
});
};
handleOk = (e) => {
console.log(e);
this.setState({
visible: false,
});
};
handleCancel = (e) => {
console.log(e);
this.setState({
visible: false,
});
};

render() {
const {getFieldDecorator, getFieldsError, getFieldError, isFieldTouched} = this.props.form;

// Only show error after a field is touched.
const userNameError = isFieldTouched('userName') && getFieldError('userName');
const passwordError = isFieldTouched('password') && getFieldError('password');
return (
<div>
<Button type="primary" onClick={this.showModal}>登录</Button>
<Modal title="Basic Modal" visible={this.state.visible}
onOk={this.handleOk} onCancel={this.handleCancel}
>
<Form layout="inline" onSubmit={this.handleSubmit}>
<FormItem
validateStatus={userNameError ? 'error' : ''}
help={userNameError || ''}
>
{getFieldDecorator('userName', {
rules: [{required: true, message: 'Please input your username!'}],
})(
<Input onChange={this.handleChange} prefix={<Icon type="user" style={{fontSize: 13}}/>}
placeholder="Username"/>
)}
</FormItem>
<FormItem
validateStatus={passwordError ? 'error' : ''}
help={passwordError || ''}
>
{getFieldDecorator('password', {
rules: [{required: true, message: 'Please input your Password!'}],
})(
<Input prefix={<Icon type="lock" style={{fontSize: 13}}/>} type="password"
placeholder="Password"/>
)}
</FormItem>
<FormItem>
<Button
type="primary"
htmlType="submit"
disabled={hasErrors(getFieldsError())}
>
Log in
</Button>
</FormItem>
</Form>
</Modal>
</div>

);
}
}

const WrappedHorizontalLoginForm = Form.create()(HorizontalLoginForm);

export default WrappedHorizontalLoginForm;


registerform.js

/**
* Created by lyy on 2017/4/12.
*/
import React from 'react'
import { Form, Input, Cascader, Select, Row, Col, Checkbox, Button,Modal } from 'antd';

const FormItem = Form.Item;
const Option = Select.Option;

const residences = [{
value: 'zhejiang',
label: 'Zhejiang',
children: [{
value: 'hangzhou',
label: 'Hangzhou',
children: [{
value: 'xihu',
label: 'West Lake',
}],
}],
}, {
value: 'jiangsu',
label: 'Jiangsu',
children: [{
value: 'nanjing',
label: 'Nanjing',
children: [{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
}],
}],
}];

class RegistrationForm extends React.Component {
state = {
confirmDirty: false,
};
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values);

fetch('http://localhost:3000/post/api/1.0/create',
{
method: "POST",
body: JSON.stringify(values),
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
}
});
}
});
};
handleConfirmBlur = (e) => {
const value = e.target.value;
this.setState({ confirmDirty: this.state.confirmDirty || !!value });
};
checkPassword = (rule, value, callback) => {
const form = this.props.form;
if (value && value !== form.getFieldValue('password')) {
callback('Two passwords that you enter is inconsistent!');
} else {
callback();
}
};
checkConfirm = (rule, value, callback) => {
const form = this.props.form;
if (value && this.state.confirmDirty) {
form.validateFields(['confirm'], { force: true });
}
callback();
};

state = { visible: false }
showModal = () => {
this.setState({
visible: true,
});
};
handleOk = (e) => {
console.log(e);
this.setState({
visible: false,
});
};
handleCancel = (e) => {
console.log(e);
this.setState({
visible: false,
});
};

render() {
const { getFieldDecorator } = this.props.form;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 6 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 14 },
},
};
const tailFormItemLayout = {
wrapperCol: {
xs: {
spa
4000
n: 24,
offset: 0,
},
sm: {
span: 14,
offset: 6,
},
},
};
const prefixSelector = getFieldDecorator('prefix', {
initialValue: '86',
})(
<Select className="icp-selector">
<Option value="86">+86</Option>
</Select>
);
return (
<div>
<Button type="primary" onClick={this.showModal}>注册</Button>
<Modal title="Basic Modal" visible={this.state.visible}
onOk={this.handleOk} onCancel={this.handleCancel}
>
<Form onSubmit={this.handleSubmit}>
<FormItem
{...formItemLayout}
label="E-mail"
hasFeedback
>
{getFieldDecorator('email', {
rules: [{
type: 'email', message: 'The input is not valid E-mail!',
}, {
required: true, message: 'Please input your E-mail!',
}],
})(
<Input />
)}
</FormItem>
<FormItem
{...formItemLayout}
label="Password"
hasFeedback
>
{getFieldDecorator('password', {
rules: [{
required: true, message: 'Please input your password!',
}, {
validator: this.checkConfirm,
}],
})(
<Input type="password" />
)}
</FormItem>
<FormItem
{...formItemLayout}
label="Confirm Password"
hasFeedback
>
{getFieldDecorator('confirm', {
rules: [{
required: true, message: 'Please confirm your password!',
}, {
validator: this.checkPassword,
}],
})(
<Input type="password" onBlur={this.handleConfirmBlur} />
)}
</FormItem>
<FormItem
{...formItemLayout}
label={(
<span>
Nickname 
</span>
)}
hasFeedback
>
{getFieldDecorator('nickname', {
rules: [{ required: true, message: 'Please input your nickname!', whitespace: true }],
})(
<Input />
)}
</FormItem>
<FormItem
{...formItemLayout}
label="Habitual Residence"
>
{getFieldDecorator('residence', {
initialValue: ['zhejiang', 'hangzhou', 'xihu'],
rules: [{ type: 'array', required: true, message: 'Please select your habitual residence!' }],
})(
<Cascader options={residences} />
)}
</FormItem>
<FormItem
{...formItemLayout}
label="Phone Number"
>
{getFieldDecorator('phone', {
rules: [{ required: true, message: 'Please input your phone number!' }],
})(
<Input addonBefore={prefixSelector} />
)}
</FormItem>
<FormItem
{...formItemLayout}
label="Captcha"
extra="We must make sure that your are a human."
>
<Row gutter={8}>
<Col span={12}>
{getFieldDecorator('captcha', {
rules: [{ required: true, message: 'Please input the captcha you got!' }],
})(
<Input size="large" />
)}
</Col>
<Col span={12}>
<Button size="large">Get captcha</Button>
</Col>
</Row>
</FormItem>
<FormItem {...tailFormItemLayout} style={{ marginBottom: 8 }}>
{getFieldDecorator('agreement', {
valuePropName: 'checked',
})(
<Checkbox>I have read the <a href="">agreement</a></Checkbox>
)}
</FormItem>
<FormItem {...tailFormItemLayout}>
<Button type="primary" htmlType="submit" size="large">Register</Button>
</FormItem>
</Form>
</Modal>
</div>

);
}
}

const WrappedRegistrationForm = Form.create()(RegistrationForm);

export default WrappedRegistrationForm;


index.js

/**
* Created by lyy on 2017/4/12.
*/
import React from 'react';
import ReactDOM from 'react-dom';
import { Layout, Menu, Breadcrumb, Icon } from 'antd';
import LoginForm from './loginform';
import RegisterForm from './registerform'

const { SubMenu } = Menu;
const { Header, Content, Sider } = Layout;

ReactDOM.render(
<Layout>
<Header className="header">
<div className="logo" />
<Menu
theme="dark"
mode="horizontal"s
defaultSelectedKeys={['2']}
style={{ lineHeight: '64px' }}
>
<Menu.Item key="1" style={{float: 'right'}}><RegisterForm/></Menu.Item>
<Menu.Item key="2" style={{float: 'right'}}><LoginForm/></Menu.Item>

</Menu>
</Header>
<Layout>
<Sider width={200} style={{ background: '#fff' }}>
<Menu
mode="inline"
defaultSelectedKeys={['1']}
defaultOpenKeys={['sub1']}
style={{ height: '100%' }}
>
<SubMenu key="sub1" title={<span><Icon type="user" />subnav 1</span>}>
<Menu.Item key="1">option1</Menu.Item>
<Menu.Item key="2">option2</Menu.Item>
<Menu.Item key="3">option3</Menu.Item>
<Menu.Item key="4">option4</Menu.Item>
</SubMenu>
<SubMenu key="sub2" title={<span><Icon type="laptop" />subnav 2</span>}>
<Menu.Item key="5">option5</Menu.Item>
<Menu.Item key="6">option6</Menu.Item>
<Menu.Item key="7">option7</Menu.Item>
<Menu.Item key="8">option8</Menu.Item>
</SubMenu>
<SubMenu key="sub3" title={<span><Icon type="notification" />subnav 3</span>}>
<Menu.Item key="9">option9</Menu.Item>
<Menu.Item key="10">option10</Menu.Item>
<Menu.Item key="11">option11</Menu.Item>
<Menu.Item key="12">option12</Menu.Item>
</SubMenu>
</Menu>
</Sider>
<Layout style={{ padding: '0 24px 24px' }}>
<Breadcrumb style={{ margin: '12px 0' }}>
<Breadcrumb.Item>Home</Breadcrumb.Item>
<Breadcrumb.Item>List</Breadcrumb.Item>
<Breadcrumb.Item>App</Breadcrumb.Item>
</Breadcrumb>
<Content style={{ background: '#fff', padding: 24, margin: 0, minHeight: 280 }}>
content
</Content>
</Layout>
</Layout>
</Layout>
, document.getElementById("root"));

后台代码

myserver.js

const express = require('express');
const mongoose = require('mongoose');
const querystring = require('querystring');

let db=mongoose.connect('mongodb://127.0.0.1:27017/db1');
let MyUser=mongoose.model("users",{
email:String,
password:String,
nickname:String,
phone:String
});

let app=express();

app.post("/post/api/1.0/create",(req,res)=>{
req.on('data',data=>{
//将获取到的数据进行解码
let decodedata = decodeURIComponent(data);
//将获取到的数据进行JSON化
let result=JSON.parse(decodedata);

let auser=new MyUser({
email:result.email,
password:result.password,
nickename:result.nickname,
phone:result.phone
});
auser.save();
});
});

//响应前端页面对query的操作请求
app.post("/post/api/1.0/query",(req,res)=>{
req.on('data',data=>{
//将获取到的数据进行解码
let decodedata = decodeURIComponent(data);
//将获取到的数据进行JSON化
let result=JSON.parse(decodedata);

let ema=result.userName;
let psw=result.password;

MyUser.findOne({
email:ema
}, function(err, docs) {
console.log(docs);
console.log(psw);
if(docs.password==psw){
console.log("登录成功");
}else{
console.log("登录失败");
}
});
});
});

app.listen(3000,function () {
console.log("运行成功");
});


相关配置文件:

package.json

{
"name": "tt",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server",
"build": "webpack -p"
},
"author": "",
"license": "ISC",
"dependencies": {
"antd": "^2.8.3",
"body-parser": "^1.17.1",
"express": "^4.15.2",
"history": "^4.2.0",
"jquery": "^3.1.0",
"jquery-form": "^4.2.1",
"mongoose": "^4.9.9",
"querystring": "^0.2.0",
"react": "^15.3.1",
"react-cookie": "^1.0.5",
"react-dom": "^15.3.1",
"react-redux": "^5.0.3",
"react-router": "^4.0.0",
"react-router-redux": "^4.0.5",
"redux": "^3.6.0",
"redux-thunk": "^2.1.0"
},
"devDependencies": {
"babel-cli": "^6.14.0",
"babel-core": "^6.14.0",
"babel-loader": "^6.2.5",
"babel-plugin-antd": "^0.5.1",
"babel-preset-es2015": "^6.14.0",
"babel-preset-react": "^6.11.1",
"babel-preset-stage-1": "^6.13.0",
"css-loader": "^0.27.3",
"style-loader": "^0.16.1",
"webpack": "^2.3.2",
"webpack-dev-server": "^2.4.2"
}
}
webpack.config.js

var path = require('path');
module.exports = {
entry:"./src/index.js",
output:{
path:path.resolve(__dirname, './dist'),
filename:"bundle.js"
},
devServer:{
inline:true,
contentBase:'./dist',
port:300
},
module:{
loaders:[
{
test:/\.js$/,
exclude:/node_modules/,
loader:'babel-loader',
query:{
presets:['es2015','react','stage-1'],
plugins:[["antd", {style:"css"}]]
}
},{
test:/\.css$/,
loader:'style-loader!css-loader'
}
]
}
};


之后打开终端,输入npm install  npm start

并通过node myserver.js 开启后台服务,然后就可以检验成果了。

最后附上项目源码地址:https://github.com/DYHlyy/React_Node_Test
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息