[Project combat] Realization of login and registration services (front-end + back-end + database)

        This example is implemented based on Vue.js and mint UI.


Table of contents

1. Database creation

Second, the connection between the back-end interface and the database

3. Front-end code implementation

1. Registration page related code

2. Registration page effect

3. Login page related code

4. Login page effect

4. Registration and login demo

5. Project file structure


1. Database creation

        Here, Navicat software is used to create a new database reg_log.sql and data table reg_log; 

        In order to realize the registration business, we design 5 fields in the database: ID, user name, password, email, and phone number.

        Save it after creation, and you can find the database and empty table we just created in the database. Then you can connect in the project.

Second, the connection between the back-end interface and the database

server folder -> 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...');
});

3. Front-end code implementation

1. Registration page related code

Project Folder -> 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. Registration page effect

3. Login page related code

Project Folder -> 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. Login page effect

4. Registration and login demo

        Enter user information as required.

        After successful registration, a pop-up window is displayed and redirected to the login page. To log in:

        login successful.

5. Project file structure

        Because the login and registration business needs to use the interface and call the database, two folders are required, one is the project folder as the front end; the other is the server folder as the back end, and both folders need to download the node_modules package and Start alone;

The loading of each module, the creation of the connection pool, and the interface are written in the app.js file under the server, and the command node app.js is used when starting; 

 The front-end page is normally written in your project folder, use the command npm run serve when starting;

Guess you like

Origin blog.csdn.net/weixin_53072519/article/details/121040183