今天咱们来实现一个用户注册的页面,在上一篇入门教程的基础上新增代码(当前的项目目录结构请参考上一篇教程),咱们将原先Vue生成的默认页面中 About 页面替换为 注册页面(效果图以下)。咱们从零开始,从最初的新建前端表单,到数据的后端验证存储,检测数据库中是否已经存在注册用户,若存在则提示“该用户已注册”,若不存在则提示“注册成功”。前端
1、前端部分vue
前端运用 Vue + Vant,首先咱们完成第一步,编写Register表单ios
1.1 咱们在 mall\src\components 目录下新建 Register.vue 文件,ajax
在 <template> </template>标签内添加:算法
<div id="register"> <van-cell-group> <van-field v-model="username" label="用户名" placeholder="请输入用户名" :rules="[{required: true, message: '请填写用户名'}]" /> <van-field v-model="password" type = "password" label="密码" placeholder="请输入密码" :rules="[{required: true, message: '请输入密码'}]" /> <van-field v-model="telnumber" label="手机号码" placeholder="请输入手机号码" :rules="[{required: true, message: '请输入手机号码'}]" /> <div style="margin: 16px;"> <van-button square block type="info" native-type="submit" size="normal" @click="onSubmit"> 提交 </van-button> </div> </van-cell-group> </div>
注:由于咱们后面还要添加发送短信验证码按钮,通常在存在一个以上按钮的状况下,不采用<form></form>表单,而用输入框+按钮就能够。数据库
在 <script> </script>标签内添加:axios
import { Field } from 'vant'; import { Button } from 'vant'; import { Toast } from 'vant'; import { Cell, CellGroup } from 'vant'; export default { components:{ [Field.name]: Field, [Button.name]: Button, [Toast.name]: Toast, [Cell.name]: Cell, [CellGroup.name]: CellGroup, }, data() { return { username: '', password: '', telnumber: '' } } }
1.2 修改 router\index.js,后端
顶端添加:api
import Register from '../components/Register.vue'
添加 routes 路由参数:安全
{ path: '/register', name: 'Register', component: Register },
1.3 修改 App.vue:
<router-link to="/about">About</router-link>
将上面的代码修改成:
<router-link to="/register">注册</router-link>
此时,从新运行Vue项目,能够看到页面:
2、 经过axios实现前端向后端传递数据
当用户填写完毕注册信息,点击提交按钮后,前端会将注册信息经过axios发送给后端服务器,并获取到返回信息,具体实现以下:
2.1 在 Register.vue中 新增 提交按钮事件:
import ajax from '@/api'; //首先引入ajax类
methods: { async onSubmit() { // async修饰符很是重要,表示该函数为异步执行 let { username, password, telnumber } = this.$data; //获取表单中的数据 let res = await ajax.register(username, password, telnumber); //await表示该语句等待 await后的语句有返回了以后,再接着执行 onSubmit的语句 console.log(res) },
}
也许你会发现 ajax.register目前为止仍是未定义的,不着急,接下来咱们就会编写 ajax类。
2.2 编写 ajax类,修改 mall\src\api\index.js,添加以下代码:
// 注册 | POST register(username, password, telnumber) { return axios.post('http://localhost:3000/users/registerUser',{username, password, telnumber}) }
OK,到这里咱们的前端部分就基本完成了,下面咱们进行后端部分开发。
3、后端 Koa2 部分
后端部分的主要实现逻辑:
1> 新建 user数据集合存储用户信息,
2> 编写router.post 路由接收前端数据,
3> 后端验证注册信息并存储返回
3.1 新建mongDB数据集合
在mall-server文件夹下新建 models 文件夹,新建 user.js :
const mongoose = require('mongoose'); var Schema = mongoose.Schema; var userSchema = new Schema({ username: {type: String, unique: true}, password: String, telnumber: String }); module.exports = mongoose.model('User',userSchema)
进一步,咱们不能够直接存储明文密码,这样安全性得不到保障,所以在存储前,须要对密码进行加密,用的 bcryptjs,在user.js 里继续添加:
const bcrypt = require('bcryptjs'); // 用于密码哈希的加密算法
/** * 对密码进行加盐 * 使用 pre 中间件在用户信息存储前执行 */ userSchema.pre('save', function(next) { // 进行加密 | 产生一个 salt bcrypt.genSalt(SALT_WORK_FACTOR, (err, salt) => { if (err) return next(err); // 结合 salt 产生新的hash bcrypt.hash(this.password, salt, (err, hash) => { if (err) return next(err); // 使用 hash 覆盖明文密码 this.password = hash; next(); }); }); });
此时咱们的数据模型已经新建完毕,若对mongoDB不熟悉的小伙伴,能够翻阅我以前的文章有介绍说明。
3.2 编写router.post 路由接收前端数据
修改 routes\user.js, 添加代码:
const userService = require('../service/user'); //引入userService类 会在下一步编写,主要用于向数据库中存储用户注册信息
router.post('/registerUser', async function (ctx) { let {username, password, telnumber} = ctx.request.body; //koa-bodyparser 解析request.body if(!username || !password || !telnumber) return ctx.body = {code: 4020,msg: '请填写完整的注册信息'}; let args = {username, password, telnumber}; const userData = await userService.accountHandle(args); //userService类会在下一步编写 ctx.body = (userData.code === 200) ? {code: 200, msg: '注册成功'} : userData })
3.3 编写userService类,用于后端验证注册信息并存储返回
在mall-server文件夹下新建,user.js:
const UserModel = require('../models/user') //引入 model class userService { async accountHandle({username, password, telnumber}) { const user = await UserModel.findOne({username}) if (user) return { code: 0, msg: '该用户已经注册' }; //若用户已存在,中止向下执行,并返回错误提示信息 let userEntity = new UserModel({ username, password, telnumber }); // 保存到数据库中 let userInfo = await userEntity.save(); return { code: 200, username: userInfo.username, password: userInfo.password, telnumber: userInfo.telnumber } } } module.exports = new userService(); // 导出这个类,注意与ES6导出类写法的差异
OK到这里,咱们就基本实现了用户注册的功能,固然还有不完善的地方,好比须要添加手机号正则验证、短信验证码、axios添加响应拦截器、JWT认证,将会在下面的文章中一块儿研究。固然,有不正确的地方,欢迎你们留意指正。