一、数据库的创建
此处以Navicat软件进行创建,新建数据库reg_log.sql与数据表reg_log;
为了实现注册业务,我们在数据库中设计ID、用户名、密码、邮箱、电话号5个字段。
创建结束后保存,便可以在数据库中找到我们刚刚创建的数据库和空表。这样就可以在项目中进行连接了。
二、后端接口与数据库的连接
server文件夹 -> app.js
// 加载Express模块 const express = require('express'); // 加载MySQL模块 const mysql = require('mysql'); // 加载bodyParser模块 const bodyParser = require('body-parser'); // 加载MD5模块 const md5 = require('md5'); // 创建MySQL连接池 const pool = mysql.createPool({ host: '127.0.0.1', //MySQL服务器地址 port: 3306, //MySQL服务器端口号 user: 'root', //数据库用户的用户名 password: '', //数据库用户密码 database: 'reg_log', //数据库名称 connectionLimit: 20, //最大连接数 charset: 'utf8' //数据库服务器的编码方式 }); // 创建服务器对象 const server = express(); server.use(bodyParser.urlencoded({ extended: false })); // 加载CORS模块 const cors = require('cors'); // 使用CORS中间件 server.use(cors({ origin: ['http://localhost:8080', 'http://127.0.0.1:8080'] })); //用户注册接口 server.post('/register', (req, res) => { //console.log(md5('12345678')); // 获取用户名和密码信息 let username = req.body.username; let password = req.body.password; //以username为条件进行查找操作,以保证用户名的唯一性 let sql = 'SELECT COUNT(id) AS count FROM reg_log WHERE username=?'; pool.query(sql, [username], (error, results) => { if (error) throw error; let count = results[0].count; if (count == 0) { // 将用户的相关信息插入到数据表 sql = 'INSERT reg_log(username,password) VALUES(?,MD5(?))'; pool.query(sql, [username, password], (error, results) => { if (error) throw error; res.send({ message: 'ok', code: 200 }); }) } else { res.send({ message: 'user exists', code: 201 }); } }); }); // 用户登录接口 server.post('/login', (req, res) => { //获取用户名和密码信息 let username = req.body.username; let password = req.body.password; // SQL语句 let sql = 'SELECT id,username FROM reg_log WHERE username=? AND password=MD5(?)'; pool.query(sql, [username, password], (error, results) => { if (error) throw error; if (results.length == 0) { //登录失败 res.send({ message: 'login failed', code: 201 }); } else { //登录成功 res.send({ message: 'ok', code: 200, result: results[0] }); } }); }); // 指定服务器对象监听的端口号 server.listen(3000, () => { console.log('server is running...'); });
三、前端代码实现
1.注册页相关代码
项目文件夹 -> Register.vue
<template> <!-- 注册页面 --> <div class="reg"> <mt-header title="用户注册"> <router-link slot="left" to="/"> 返回首页 </router-link> <router-link to="/login" slot="right">去登录</router-link> </mt-header> <mt-field type="text" label="用户名" placeholder="请输入用户名" v-model="name" :state="nameState" @blur.native.capture="checkName"></mt-field> <!-- @blur失焦,输入框在输入完成、移到其他地方时进行验证 --> <mt-field type="password" label="密码" placeholder="请输入密码" v-model="pwd" :state="pwdState" @blur.native.capture="checkPwd"></mt-field> <mt-field type="password" label="确认密码" placeholder="再次输入密码" v-model="repwd" :state="repwdState" @blur.native.capture="checkrePwd"></mt-field> <mt-field label="邮箱" placeholder="请输入邮箱" type="email" v-model="email" :state="emailState" @blur.native.capture="checkEmail"></mt-field> <mt-field label="手机号" placeholder="请输入手机号" type="tel" v-model="phone" :state="phoneState" @blur.native.capture="checkPhone"></mt-field> <mt-field label="生日" placeholder="请输入生日" type="date" v-model="birthday"></mt-field> <mt-button class="btn" type="primary" size="large" @click="checkForm">注册</mt-button> </div> </template> <style scope> .reg .btn { background-color: #d86931; width: 190px; border-radius: 0; border: 0; margin: auto; } .reg .mint-cell-wrapper { line-height: 80px; } .reg { margin-top: 14%; } .reg .mint-header { background-color: #d86931; } .reg .btn { background-color: #d86931; } </style> <script> export default { data() { return { name: "", //双向数据绑定 用户名输入框 nameState: "", //处理用户名输入框的动态更新 pwd: "", pwdState: "", repwd: "", repwdState: "", email: "", emailState: "", phone: "", phoneState: "", birthday: "", }; }, methods: { // 封装各个字段的验证方法: // 1.验证用户名 checkName() { //事件处理函数:处理点击按钮验证表单 let reg = /^[a-zA-Z0-9\u4E00-\u9FA5]{2,6}$/; if (reg.test(this.name)) { this.nameState = "success"; return true; } else { this.nameState = "error"; return false; } }, // 2.验证密码 checkPwd() { let reg = /^\d{6}$/; if (reg.test(this.pwd)) { this.pwdState = "success"; return true; } else { this.pwdState = "error"; return false; } }, // 3.重复输入密码 checkrePwd() { let reg = /^\d{6}$/; if (reg.test(this.repwd) && this.pwd == this.repwd) { this.repwdState = "success"; return true; } else { this.repwdState = "error"; return false; } }, // 4.验证邮箱格式 checkEmail() { let reg = /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/; if (reg.test(this.email)) { this.emailState = "success"; return true; } else { this.emailState = "error"; return false; } }, // 5.验证手机号 checkPhone() { let reg = /^1[3|5|7|8][0-9]\d{8}$/; if (reg.test(this.phone)) { this.phoneState = "success"; return true; } else { this.phoneState = "error"; return false; } }, checkForm() { // 点击注册按钮后调用此方法,验证用户名、密码、二次密码是否均正确,正确则发送axios请求 if (this.checkName() && this.checkPwd() && this.checkrePwd()) { console.log(`验证成功,执行注册业务......`); // 发送注册(post)请求 this.axios .post("/register", `username=${this.name}&password=${this.pwd}`) .then((result) => { console.log(result); if (result.data.code == 200) { // 弹窗提示注册成功 this.$toast({ message: "注册成功", position: "bottom", duration: 3000, }); // 注册成功后直接跳转到登录页 this.$router.push("/login"); } else if (result.data.code == 201) { this.$toast({ message: "用户已存在,请重新注册", position: "bottom", duration: 3000, }); } }); } }, }, }; </script>
2.注册页效果
3.登录页相关代码
项目文件夹 -> Login.vue
<template> <!-- 登录页面 --> <div class="log"> <span class="login">请登录</span> <span class="reg"> <router-link to="/register">先去注册</router-link> </span> <!-- mint ui的表单组件 --> <mt-field type="text" label="用户名" placeholder="请输入用户名" v-model="name" :state="nameState" @blur.native.capture="checkName"></mt-field> <mt-field type="password" label="密码" placeholder="请输入密码" v-model="pwd" :state="pwdState" @blur.native.capture="checkPwd"></mt-field> <hr style="width: 85%" /> <mt-button class="btn" type="primary" size="large" @click="checkForm">登录</mt-button> </div> </template> <style scoped> .log .reg { font-size: 18px; } .log .login { font-size: 24px; font-family: "楷体"; font-weight: 700; margin-left: 5px; margin-right: 210px; line-height: 80px; } .log { margin-top: 20%; } .log .btn { background-color: #d86931; width: 190px; border-radius: 0; border: 0; margin: auto; } .log .btn1 { background-color: white; border: 2px solid #d86931; color: #d86931; width: 190px; margin: auto; margin-top: 30px; } </style>> <script> export default { namespaced: true, data() { return { name: "", //双向数据绑定 用户名输入框 nameState: "", //处理用户名输入框的动态更新 pwd: "", pwdState: "", }; }, methods: { // 封装验证方法: // 1.验证用户名 checkName() { //事件处理函数:处理点击按钮验证表单 let reg = /^[a-zA-Z0-9\u4E00-\u9FA5]{2,6}$/; //2-6位的数字、字母、汉字 if (reg.test(this.name)) { this.nameState = "success"; return true; } else { this.nameState = "error"; return false; } }, // 2.验证密码 checkPwd() { let reg = /^\d{6}$/; if (reg.test(this.pwd)) { this.pwdState = "success"; return true; } else { this.pwdState = "error"; return false; } }, checkForm() { // 点击登录按钮后调用此方法,同时验证用户名和密码 if (this.checkName() && this.checkPwd()) { // 发送登录(post)请求 this.axios .post("/login", `username=${this.name}&password=${this.pwd}`) .then((result) => { console.log(result); if (result.data.code == 200) { // 弹窗提示登录成功 this.$toast({ message: `欢迎您 ${this.name}`, position: "bottom", duration: 3000, }); // 修改vuex中用户登录状态 this.$store.commit("loginok", this.name); // 将islogin与username存入sessionStorage sessionStorage.setItem("islogin", true); sessionStorage.setItem("username", this.name); // 登录成功后直接跳转到首页 this.$router.push("/club"); } else { this.$toast({ message: "登录失败,请检查您的用户名和密码", position: "bottom", duration: 3000, }); } }); } }, }, }; </script>
4.登录页效果
四、注册登录演示
按正则要求输入用户信息。
注册成功后弹窗显示并且跳转至登录页。 进行登录:
登录成功。
五、项目文件结构
因为登陆注册业务需要使用到接口并调用数据库,所以需要两个文件夹,一个是项目文件夹,作为前端;一个是server文件夹,作为后端,且这两个文件夹都需要下载 node_modules 包并单独启动;
各模块的加载、连接池的创建以及接口写于 server 下的 app.js 文件,启动时使用命令 node app.js;
而前端的页面就正常在你的项目文件夹中书写,启动时使用命令 npm run serve;