前两个月一直学习vue,node.js,但没有真正地动手作项目,刚好遇上公司要求咱们作一个的登陆注册的独立运行系统,趁着这个机会学习巩固下本身以前学的内容。前端使用 vue,后端用 Express 作服务端提供数据接口,数据库用 MySql。 实现对数据库的增改查操做。前端
demo 要求vue
完成一套能够独立运行的前端系统,包括注册,登陆,我的中心3个功能模块。node
首先介绍下项目的目录结构mysql
首先全局安装: npm install -g vue-cli
webpack
安装依赖,实如今package.json 中对应添加相应的版本,而后执行 npm install
ios
"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 +"'";
}
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
}
}
})
});
//获取用户信息
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......即服务端启动成功。
这里主要介绍 登陆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
复制代码
一成天加一个下午,终于调通了,在数据库那边遇到了好多问题,不过通过不断的尝试终于解决了。
效果图
源码不当之处,还请指正,欢迎 star
参考了如下vue-manage-system,海岛心hey,罗坤