vue+node---使用element框架实现的前后台用户登录注册功能

19 篇文章 0 订阅

为了更进一步清晰地了解前台数据向后台提交的过程,更好地加强巩固前端开发学习,整理了基础的【前后台用户登录注册功能】实现代码。后台通过node.js开发,数据存储在sqlite中,前台vue+element完成开发,首先功能实现效果展示如下:

 

             

 

一、后台node.js

安装express、body-parser 【npm install express body-parser 】,关于express介绍,见https://blog.csdn.net/maidu_xbd/article/details/86632618  body-parser用于处理post请求

全局安装sqlite3【npm install sqlite3 -g】sqlite使用说明详细见https://blog.csdn.net/maidu_xbd/article/details/99977786

server.js完整代码:

const express = require("express")
const bodyParser = require("body-parser")

const sqlite3 = require("sqlite3").verbose()
const app = express()
// sqlites数据库地址
let sqliteDbPath = "C:\\Users\\lenovo\\Desktop\\Demo.db"
// 打开sqlites数据库
var db = new sqlite3.Database(sqliteDbPath)
app.use(bodyParser.json()) // for parsing application/json
// app.get('/', (req, res) => res.send('Hello World!'))

// 登录请求处理
app.post("/submitLogin", function(req, res) {
    var username = req.body.name
    var password = req.body.password
    db.all(`select * from user where username=?`, username, function(err, row) {
        if (err) throw err
        else {
            // console.log(row)
            if (row == "") {
                // 如果查找数据库用户名为空,则无此用户
                res.send({ status: 500, msg: "此用户不存在" })
            } else {
                // console.log(row[0].password)
                if (row[0].password != password) {
                    // 检验密码是否一致
                    res.send({ status: 500, msg: "密码错误" })
                } else {
                    res.send({ status: 200, msg: "登录成功" })
                }
            }
        }
    })
})

// 注册请求处理
app.post("/submitRegister", (req, res) => {
    var username = req.body.name
    var email = req.body.email
    var password = req.body.password
    console.log(username)
    db.all("select * from user where username=?", username, function(err, row) {
        if (err) throw err
        else {
            // console.log(row)
            if (row == "") {
                // 如果查找数据库用户名为空,则无此用户,在数据库中存储用户名,密码和邮箱信息
                // var sql_add = db.prepare(`insert into user (username, password, email) values('buding1', '1111', '221@sdsd.com')`)
                var sql_add = db.prepare(`insert into user (username, password, email) values(?,?,?)`)
                sql_add.run(username, password, email)
                res.send({ status: 200, msg: "恭喜你,注册成功!" })
            } else {
                res.send({ status: 500, msg: "用户名已注册,请更换用户名" })



            }
        }
    })
})


app.listen(9999, () => console.log("Example app listening on port 9999!"))

注意:接口文件 

  1. 用户登录验证

前台将用户输入的用户名和密码传入到后台验证

url

/submitLogin

method

POST

request

{name:userName,password:password}

response

后台验证成功:{status:200,msg:”登录成功}

后台密码验证失败:{status:500,msg:”密码错误}

后台用户不存在验证失败:{status:500,msg:”此用户不存在}

 

2. 用户注册验证

前台将用户输入的用户名、邮箱和密码传入到后台验证

url

/submitRegister

method

POST

request

{name:userName, "email":email, password:password}

response

后台验证成功:{status:200,msg:”恭喜你,注册成功}

后台验证失败:{status:500,msg:”用户名已注册,请更换用户名}

二、前台vue+element

安装element-ui 【npm i element-ui -S】

安装axios:【npm install axios --save-dev】

详细见https://blog.csdn.net/maidu_xbd/article/details/88566665

Login.vue完整代码如下:

<template>
  <div class="login-demo">
    <div class="login-wrap">
      <el-row type="flex" justify="center">
        <!-- 登录框 -->
        <el-form ref="loginForm" :rules="formRules" :model="user" status-icon label-width="70px">
          <el-tabs :stretch="true" v-model="activeName" @tab-click="handleClick">
            <el-tab-pane label="登录" name="login">
              <el-form-item prop="username" label="用户名">
                <el-input v-model="user.username" placeholder="请输入用户名"></el-input>
              </el-form-item>
              <el-form-item prop="password" label="密码">
                <el-input v-model="user.password" show-password placeholder="请输入密码">
                  <template slot="prepend"></template>
                </el-input>
              </el-form-item>
              <el-checkbox id="savePassword" checked="checked" @click="savePassword()">记住密码</el-checkbox>
              <router-link to="/forgetPassword">忘记密码</router-link>
              <br>
              <br>
              <el-form-item>
                <el-button type="primary" @click="doLogin('loginForm')">登 录</el-button>
              </el-form-item>
            </el-tab-pane>
            <!-- 注册框 -->
            <el-tab-pane label="注册" name="register">
              <el-form-item prop="username" label="用户名">
                <el-input v-model="user.username" placeholder="请输入用户名"></el-input>
              </el-form-item>
              <el-form-item prop="email" label="邮箱">
                <el-input v-model="user.email" placeholder="请输入邮箱"></el-input>
              </el-form-item>
              <el-form-item prop="password" label="设置密码">
                <el-input v-model="user.password" show-password placeholder="请输入密码"></el-input>
              </el-form-item>
              <el-form-item>
                <el-button type="primary" icon @click="doRegister('loginForm')">注册账号</el-button>
              </el-form-item>
            </el-tab-pane>
          </el-tabs>
        </el-form>
      </el-row>
    </div>
  </div>
</template>
<script>
import axios from "axios";
export default {
  name: "login",
  data() {
    return {
      activeName: "login",
      checked: false,
      user: {
        username: "",
        password: ""
      },
      // 通过 formRules 属性传入约定的验证规则
      formRules: {
        username: [{ required: true, message: "用户名不能为空", trigger: "blur" }],
        password: [
          { required: true, message: "密码不能为空", trigger: "blur" },
          { type: "string", min: 6, message: "密码不能小于6位", trigger: "blur" }
        ],
        // bug--由于此处登录和注册共用一个el-form,因此只能绑定一个rules,如果邮箱设置为必填,将导致无法登陆。一般情况下,将登录和注册分别放在不同的el-form中,为它们设置不同的rules
        email: [
          // { required: true, message: "请输入邮箱地址", trigger: "blur"  },
          { type: "email", message: "请输入正确的邮箱地址", trigger: ["blur", "change"] }
        ]
      }
    }
  },
  created() {},
  methods: {
    // 登录
    doLogin(form) {
      this.$refs[form].validate((valid) => {
        if (valid) {
          axios
            .post("/submitLogin/", {
              // .post("/api/login/", {
              name: this.user.username,
              password: this.user.password
            })
            .then(res => {
              //  console.log("输出response.data", res.data);
              if (res.data.status === 200) {
                this.$router.push({ path: "/welcome" });
              } else {
                this.$message.error(res.data.msg)
              }
            });
        } else {
          return false;
        }
      });
    },
    // 注册账号
    doRegister(form) {
      this.$refs[form].validate((valid) => {
        if (valid) {
          console.log(valid);
          axios
            .post("/submitRegister/", {
              name: this.user.username,
              email: this.user.email,
              password: this.user.password
            })
            .then(res => {
              // console.log("输出response.data", res.data);
              if (res.data.status === 200) {
                this.$message.success(res.data.msg)
                this.activeName = "login";
              } else {
                this.$message.error(res.data.msg);
              }
            });
        } else {
          return false;
        }
      });
    },
    handleClick(tab, event) {
      console.log(tab, event);
    },
    // 记住密码
    savePassword() {
      if (document.getElementById("savePassword").checked) {
        var username = this.user.username;
        var password = this.user.password;
        wind
        ow.sessionStorage.username = username;
        window.sessionStorage.password = password;
        localStorage.rmbPassword = true;
      } else {
        localStorage.rmbPassword = false;
      }
    }
  }
}

</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
/* 公共样式 */
li {
  list-style: none;
  float: left;
}

.login-demo {
  position: fixed;
  width: 100%;
  height: 100%;
  background: url("../assets/images/bg2.png") no-repeat;
  background-size: cover;
  top: 0px;
  left: 0px;
  overflow: hidden;
}

.login-wrap {
  background: url("../assets/images/login_bg.png") no-repeat;
  width: 400px;
  height: 310px;
  margin: 175px auto;
  margin-left: 272px;
  border-radius: 6px;
  line-height: 20px;
  padding-top: 0px;
}

.el-tabs>>>.el-tabs__item {
  font-size: 18px;
  margin: 5px auto;
}

.el-tabs__nav {
  font-size: 18px;
}

a {
  text-decoration: none;
  color: #606266;
  font-size: 14px;
  float: right;
}

a:hover {
  color: coral;
}

.el-checkbox {
  text-indent: 4px;
}

>>>.el-form-item__label {
  padding: 0px 4px 0 0;
}

>>>.el-checkbox__label {
  padding-left: 0px;
}

.el-button {
  width: 118%;
  margin-left: -40px;
  background-color:
    #16696a;
  letter-spacing: 5px;
  border: 0px;
}

</style>

ForgetPassword.vue完整代码如下:
备注:发送邮件尚未做

<template>
  <div class="forget-password">
    <div id="content">
      <h3>{{message}}</h3>
      <el-form :rules="rules" label-width="40px" class="demo-ruleForm">
        <el-form-item label="邮箱" prop="pass">
          <el-input type="input" v-model="email" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="sumbitForm">确定</el-button>
          <el-button type="primary" @click="cancle">取消</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>
<script>
import axios from "axios";
export default {
  name: "forget-password",
  data() {
    return {
      message: "找回密码!",
      email: "",
      rules: {
        email: [{ message: "邮箱不能为空", trigger: "blur" }]
      }
    };
  },
  methods: {
    sumbitForm() {
      if (!this.email) {
        this.$message.error("请输入邮箱!");
        return;
      } else {
        var reg = /^(?:\w+\.?)*\w+@(?:\w+\.)*\w+$/;
        if (!reg.test(this.email)) {
          this.$message.error("邮箱格式不正确,请重新输入!");
          this.email.focus();
          return false;
        } else {
          this.$message("发送邮件");
          //    axios
          //     .post("/register/", {
          //       name: this.user.username,
          //       email: this.user.email,
          //       password: this.user.password
          //     })
          //     .then(res => {
          //       // console.log("111输出response.data", res.data);
          //       // console.log("111输出response.data.status", res.data.status);
          //       if (res.data.status === 200) {
          //         this.$router.push({ path: "/" });
          //       } else {
          //         alert("您输入的用户名已存在!");
          //       }
          //     });
        }
      }
    },
    cancle() {
      this.$router.go(-1);
    }
  }
};

</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.forget-password {
  position: fixed;
  width: 100%;
  height: 100%;
  background: url("../assets/images/bg4.png") no-repeat;
  background-size: cover;
  top: 0px;
  left: 0px;
  overflow: hidden;
}

#content {
  width: 400px;
  height: 200px;
  margin: 100px auto;
  /* background: #d7e695; */
  background-color: rgba(0, 0, 0, 0.2);
  padding: 10px;
  border-radius: 6px;
}

</style>

注意:【config】下【index.js】修改配置文件

proxyTable: {
      '/': {

        target: 'http://localhost:9999',
        changeOrigin: true,
        pathRewrite: {
          '^/': ''

        }
      }
    },

 

Vue-Element-Admin是一个基于Vue.js和Element UI的后台管理系统模板,主要包括用户管理、权限管理、菜单管理、角色管理、日志管理等功能模块。其中,登录功能是系统的核心功能之一,下面详细介绍Vue-Element-Admin登录功能的具体实现。 1. 登录页面 登录页面是用户登录系统的入口,需要提供用户名和密码输入框、验证码输入框和登录按钮。在Vue-Element-Admin中,登录页面的实现主要包括以下几个部分: (1)路由配置:在路由配置文件(router/index.js)中添加登录页面的路由配置。 (2)页面布局:使用Element UI中的布局组件实现登录页面的布局。 (3)表单验证:使用Vue.js中的表单验证功能验证用户名、密码和验证码的输入合法性。 (4)登录请求:使用axios库向后台发送登录请求,验证用户登录信息是否正确。 (5)登录状态保存:将登录成功后返回的token保存在本地,供后续请求时使用。 2. 登录请求 在Vue-Element-Admin中,登录请求是通过axios库发送的。axios是一个基于Promise的HTTP库,可以用于浏览器和Node.js平台。在发送登录请求时,需要设置请求的URL、请求方法、请求头和请求体等参数。 以下是发送登录请求的代码示例: ```javascript import axios from 'axios' export function login(username, password, code, uuid) { const data = { username, password, code, uuid } return axios({ url: '/auth/login', method: 'post', headers: { 'Content-Type': 'application/json;charset=UTF-8' }, data }) } ``` 在上述代码中,login函数接收四个参数,分别是用户名、密码、验证码和UUID。其中,UUID是用于生成验证码的唯一标识符。login函数返回一个Promise对象,该对象的then方法用于处理登录成功后的逻辑,catch方法用于处理登录失败后的逻辑。 3. 登录状态保存 在Vue-Element-Admin中,登录状态是通过Vuex库保存的。Vuex是一个专为Vue.js应用程序开发的状态管理模式,可以用于集中管理应用程序中的所有组件的状态。 在登录成功后,后台会返回一个token,该token需要保存在本地,以便后续请求时使用。以下是保存登录状态的代码示例: ```javascript import { login } from '@/api/user' import { setToken } from '@/utils/auth' const state = { token: '' } const mutations = { SET_TOKEN: (state, token) => { state.token = token } } const actions = { login({ commit }, userInfo) { const { username, password, code, uuid } = userInfo return new Promise((resolve, reject) => { login(username, password, code, uuid).then(response => { const { data } = response commit('SET_TOKEN', data.token) setToken(data.token) resolve() }).catch(error => { reject(error) }) }) } } ``` 在上述代码中,login函数接收一个userInfo对象作为参数,该对象包含用户名、密码、验证码和UUID等信息。login函数返回一个Promise对象,该对象的then方法用于处理登录成功后的逻辑,catch方法用于处理登录失败后的逻辑。 4. 登录状态验证 在Vue-Element-Admin中,登录状态验证是通过路由拦截实现的。路由拦截是Vue.js中的一种权限控制方式,可以在路由跳转用户登录状态进行验证,从而实现页面的权限控制。 以下是路由拦截的代码示例: ```javascript import router from './router' import { getToken } from '@/utils/auth' const whiteList = ['/login'] router.beforeEach(async(to, from, next) => { const hasToken = getToken() if (hasToken) { if (to.path === '/login') { next({ path: '/' }) } else { next() } } else { if (whiteList.indexOf(to.path) !== -1) { next() } else { next(`/login?redirect=${to.path}`) } } }) ``` 在上述代码中,beforeEach函数用于路由拦截,该函数接收三个参数,分别是要跳转的路由对象、当路由对象和next函数。在beforeEach函数中,首先获取本地的token,如果token存在,则跳转到要访问的路由页面,否则跳转到登录页面。如果要访问的路由页面在白名单中,则直接跳转到该页面,否则跳转到登录页面,并将要访问的页面作为参数传递给登录页面。
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值