Node.js+Mysql+Vue+ElementUI 實現登陸註冊註銷功能

前兩個月一直學習vue,node.js,但沒有真正地動手作項目,剛好遇上公司要求咱們作一個的登陸註冊的獨立運行系統,趁着這個機會學習鞏固下本身以前學的內容。前端使用 vue,後端用 Express 作服務端提供數據接口,數據庫用 MySql。
實現對數據庫的增改查操做。前端

demo 要求vue

完成一套能夠獨立運行的前端系統,包括註冊,登陸,我的中心3個功能模塊。node

  • 1.不限定開發技術和開發框架。
  • 2.用戶包括如下信息:用戶名稱,帳號名稱,密碼,密碼重複,郵箱,手機,身份證,出生日期,性別
  • 3.註冊時須要對用戶信息進行非空校驗和格式校驗,兩次密碼一致性校驗,表單提交須要注意防重複提交
  • 4.登陸時須要有驗證碼,須要對驗證碼正確性進行校驗,驗證碼校驗失敗自動更新驗證碼,提供手動更新驗證碼操做
  • 5.登陸成功展現我的中心,提供修改我的信息操做,退出操做,修改密碼操做
  • 附加:我的中心提供頭像以及修改頭像功能

準備工做

node.js

mysql

git

express

element-UI

目錄結構

首先介紹下項目的目錄結構mysql

圖片描述

vue-cli 建立一個基於 webpack 的 Vue 登陸註冊系統項目

首先全局安裝: npm install -g vue-cliwebpack

安裝依賴,實如今package.json 中對應添加相應的版本,而後執行 npm installios

"dependencies": {
    "axios": "^0.15.3",
    "babel-polyfill": "^6.23.0",
    "body-parser": "^1.18.2",
    "element-ui": "1.3.1",
    "mysql": "^2.15.0",
    "vue": "^2.3.2",
    "vue-core-image-upload": "2.1.11",
    "vue-datasource": "1.0.9",
    "vue-router": "^2.3.1",
  },

服務端配置

在項目根文件夾下建立一個 service 文件夾。而後建立下面四個文件:
db/db.js --- 用來添加 MySQL 配置git

module.exports = {
    mysql: {
        host: 'localhost',
        user: 'root',
        password: '',
        port: '3306',
        database: 'login'
    }
}

app.js --- Express服務器入口文件github

const userApi = require('./api/userApi');
const fs = require('fs');
const path = require('path');
const bodyParser = require('body-parser');
const express = require('express');
const app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded())

app.use('/api/user', userApi);

app.listen(3000);
console.log('success listen at port: 3000')

db/sqlMap.js----SQL語句映射文件,這裏主要是對數據庫的增改查操做。web

var sqlMap = {
    user: {
        add: 'insert into user (username, account, password, repeatPass, email, phone, card, birth, sex) values (?,?,?,?,?,?,?,?,?)',
        select_name: 'select * from user', 
        update_user: 'update user set'
    }
}

module.exports = sqlMap;

其中查詢語句一直有問題vue-router

select_name: 'select * from user where username = ?',

node 一直報錯,後來,將 where username = ?放在api中拼接
具體見下,若是你有更好的解決方案,也請多指教。

router.post('/login', (req, res) => {
    var sql_name = $sql.user.select_name;
    // var sql_password = $sql.user.select_password;
    var params = req.body;
    console.log(params);
    if (params.name) {
        sql_name += "where username ='"+ params.name +"'";
    }
    var keywords = JSON.parse(Object.keys(params)[0]);
    conn.query(sql_name, params.name, function(err, result) {
        if (err) {
            console.log(err);
        }
        // console.log(result);
        if (result[0] === undefined) {
            res.send('-1')   //查詢不出username,data 返回-1
        } else {
            var resultArray = result[0];
            console.log(resultArray.password);
           // console.log(keywords);
            if(resultArray.password === keywords.password) {
                jsonWrite(res, result);
            } else {
                res.send('0')   //username
            }
        }
    })
});

api/userApi.js ---- 測試用api示例

var models = require('../db/db');
var express = require('express');
var router = express.Router();
var mysql = require('mysql');
var $sql = require('../db/sqlMap');

var conn = mysql.createConnection(models.mysql);

conn.connect();

var jsonWrite = function(res, ret) {
    if(typeof ret === 'undefined') {
        res.send('err');
    } else {
        console.log(ret);
        res.send(ret);
    }
}

var dateStr = function(str) {
    return new Date(str.slice(0,7));
}

// 增長用戶接口
router.post('/addUser', (req, res) => {
    var sql = $sql.user.add;
    var params = req.body;
    console.log(params);
    console.log(params.birth);
    conn.query(sql, [params.name, params.account, params.pass, params.checkPass,
                    params.email, params.phone, params.card, dateStr(params.birth), params.sex], function(err, result) {
        if (err) {
            console.log(err);
        }
        if (result) {
            jsonWrite(res, result);
        }
    })
});

//查找用戶接口
router.post('/login', (req, res) => {
    var sql_name = $sql.user.select_name;
    // var sql_password = $sql.user.select_password;
    var params = req.body;
    console.log(params);
    if (params.name) {
        sql_name += "where username ='"+ params.name +"'";
    }
    conn.query(sql_name, params.name, function(err, result) {
        if (err) {
            console.log(err);
        }
        // console.log(result);
        if (result[0] === undefined) {
            res.send('-1')   //查詢不出username,data 返回-1
        } else {
            var resultArray = result[0];
            console.log(resultArray.password);
           // console.log(keywords);
            if(resultArray.password === params.password) {
                jsonWrite(res, result);
            } else {
                res.send('0')   //username
            }
        }
    })
});

//獲取用戶信息
router.get('/getUser', (req, res) => {
    var sql_name = $sql.user.select_name;
    // var sql_password = $sql.user.select_password;
    var params = req.body;
    console.log(params);
    if (params.name) {
        sql_name += "where username ='"+ params.name +"'";
    }
    conn.query(sql_name, params.name, function(err, result) {
        if (err) {
            console.log(err);
        }
        // console.log(result);
        if (result[0] === undefined) {
            res.send('-1')   //查詢不出username,data 返回-1
        } else {
            jsonWrite(res, result);
        }
    })
});

//更新用戶信息
router.post('/updateUser', (req, res) => {
    var sql_update = $sql.user.update_user;
    var params = req.body;
    console.log(params);
    if (params.id) {
        sql_update  += " email = '" + params.email +
                        "',phone = '" + params.phone +
                        "',card = '" + params.card +
                        "',birth = '" + params.birth +
                        "',sex = '" + params.sex +
                        "' where id ='"+ params.id + "'";
    }    
    conn.query(sql_update, params.id, function(err, result) {
        if (err) {
            console.log(err);
        }
        console.log(result);
        if (result.affectedRows === undefined) {
            res.send('更新失敗,請聯繫管理員')   //查詢不出username,data 返回-1
        } else {
            res.send('ok'); 
        }
    })
});

//更改密碼
router.post('/modifyPassword', (req, res) => {
    var sql_modify = $sql.user.update_user;
    var params = req.body;
    console.log(params);
    if (params.id) {
        sql_modify +=  " password = '" + params.pass +
                        "',repeatPass = '" + params.checkPass +
                        "' where id ='"+ params.id + "'";
    }
    conn.query(sql_modify, params.id, function(err, result) {
        if (err) {
            console.log(err);
        }
        // console.log(result);
        if (result.affectedRows === undefined) {
            res.send('修改密碼失敗,請聯繫管理員')   //查詢不出username,data 返回-1
        } else {
            res.send('ok'); 
        }
    })
});


module.exports = router;

此時在service文件夾下執行node app(這裏也能夠加載package.json中,而後使用npm執行)看到success listen at port:3000......即服務端啓動成功。

vue 登陸組件

這裏主要介紹 登陸login.vue組件

<template>
    <div class="login-wrap">
        <div class="ms-title">登陸管理系統</div>
        <div class="ms-login">
            <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="0px" class="demo-ruleForm">
                <div v-if="errorInfo">
                    <span>{{errInfo}}</span>
                </div>
                <el-form-item prop="name">
                    <el-input v-model="ruleForm.name" placeholder="帳號" ></el-input>
                </el-form-item>
                <el-form-item prop="password">
                    <el-input type="password" placeholder="密碼" v-model="ruleForm.password" @keyup.enter.native="submitForm('ruleForm')"></el-input>
                </el-form-item>
                <el-form-item  prop="validate">
                    <el-input v-model="ruleForm.validate" class="validate-code" placeholder="驗證碼" ></el-input>
                    <div class="code" @click="refreshCode">
                        <s-identify :identifyCode="identifyCode"></s-identify>
                    </div>
                </el-form-item>
                <div class="login-btn">
                    <el-button type="primary" @click="submitForm('ruleForm')">登陸</el-button>
                </div>
                <p style="font-size:14px;line-height:30px;color:#999;cursor: pointer;float:right;" @click="handleCommand()">註冊</p>  
            </el-form>
        </div>
    </div>    
</template>

<script>
    export default {
        name: 'login',
        data() {
            return {
                identifyCodes: "1234567890",
                identifyCode: "",
                errorInfo : false,
                ruleForm: {
                    name: '',
                    password: '',
                    validate: ''                    
                },
                rules: {
                    name: [
                        { required: true, message: '請輸入用戶名', trigger: 'blur' }
                    ],
                    password: [
                        { required: true, message: '請輸入密碼', trigger: 'blur' }
                    ],
                    validate: [
                        { required: true, message: '請輸入驗證碼', trigger: 'blur' }
                    ]
                }
            }
        },
        mounted() {
            this.identifyCode = "";
            this.makeCode(this.identifyCodes, 4);
        },
        methods: {
            submitForm(formName) {
                const self = this;
                self.$refs[formName].validate((valid) => {
                    if (valid) {
                        localStorage.setItem('ms_username',self.ruleForm.name);
                        localStorage.setItem('ms_user',JSON.stringify(self.ruleForm));
                        console.log(JSON.stringify(self.ruleForm));                        
                        self.$http.post('/api/user/login',JSON.stringify(self.ruleForm))
                        .then((response) => {
                            console.log(response);
                            if (response.data == -1) {
                                self.errorInfo = true;
                                self.errInfo = '該用戶不存在';
                                console.log('該用戶不存在')
                            } else if (response.data == 0) {
                                console.log('密碼錯誤')
                                self.errorInfo = true;
                                self.errInfo = '密碼錯誤';
                            } else if (response.status == 200) {
                                self.$router.push('/readme');
                            }                            
                        }).then((error) => {
                            console.log(error);
                        })
                    } else {
                        console.log('error submit!!');
                        return false;
                    }
                });
            },
            handleCommand() {
                this.$router.push('/register');
            },
            randomNum(min, max) {
                return Math.floor(Math.random() * (max - min) + min);
            },
            refreshCode() {
                this.identifyCode = "";
                this.makeCode(this.identifyCodes, 4);
            },
            makeCode(o, l) {
                for (let i = 0; i < l; i++) {
                    this.identifyCode += this.identifyCodes[
                    this.randomNum(0, this.identifyCodes.length)
                    ];
                }
                console.log(this.identifyCode);
            }
        }
    }
</script>

<style scoped>
    .login-wrap{
        position: relative;
        width:100%;
        height:100%;
    }
    .ms-title{
        position: absolute;
        top:50%;
        width:100%;
        margin-top: -230px;
        text-align: center;
        font-size:30px;
        color: #fff;

    }
    .ms-login{
        position: absolute;
        left:50%;
        top:50%;
        width:300px;
        height:240px;
        margin:-150px 0 0 -190px;
        padding:40px;
        border-radius: 5px;
        background: #fff;
    }
    .ms-login span {
        color: red;
    }
    .login-btn{
        text-align: center;
    }
    .login-btn button{
        width:100%;
        height:36px;
    }
    .code {
        width: 112px;
        height: 35px;
        border: 1px solid #ccc;
        float: right;
        border-radius: 2px;
    }
    .validate-code {
        width: 136px;
        float: left;
    }
</style>

設置代理與跨域

執行完上述3步以後,在根目錄下執行 npm run dev,,而後輸入一組數據,點擊保存,你會發現會報一個錯誤:vue-resource.common.js?e289:1071 POST http://localhost:8082/api/user/login 404 (Not Found).
這是因爲直接訪問8082端口,是訪問不到的,因此這裏須要設置一下代理轉發映射.

vue-cli的config文件中有一個proxyTable參數,用來設置地址映射表,能夠添加到開發時配置(dev)中

dev: {
    // ...
    proxyTable: {
        '/api': {
            target: 'http://127.0.0.1:3000/api/',
            changeOrigin: true,
            pathRewrite: {
                '^/api': ''
            }
        }
    },
    // ...
}

即請求/api時就表明http://127.0.0.1:3000/api/(這裏要寫ip,不要寫localhost),
changeOrigin參數接收一個布爾值,若是爲true,這樣就不會有跨域問題了。

項目中要求防止屢次提交,實際上就是防抖操做:
具體請移步節流和防抖

項目運行

//本地開發
//開啓前端服務,瀏覽器訪問 http://localhost:8082
npm run dev
//開啓後端服務
cd service
node app

一成天加一個下午,終於調通了,在數據庫那邊遇到了好多問題,不過通過不斷的嘗試終於解決了。

效果圖

clipboard.png

clipboard.png

clipboard.png

源碼不當之處,還請指正,歡迎 star

參考瞭如下vue-manage-system海島心hey羅坤

相關文章
相關標籤/搜索