0.基本结构
技术栈:
前端:vue、ajax
后端: node.js
数据库: mysql
UI框架:element-UI
环境:vue-cli
目录结构:
页面逻辑:
顶栏是一直存在的,从首页点击按钮就会进入到登录/注册页面(嘿嘿。。一般登录和注册是放不同页面的。因为懒,所以放在同一页了)
注册和登录时会在后端进行一波验证
注册成功后,路由跳转到相应页面;登陆成功还会改变顶栏显示的内容;退出登录后回到首页
1.搭建构架
首先在vscode中搭好vue环境,安装好依赖
npm install
npm install mysql
npm install vue-router
npm i element-ui -S
路由:
/router/index.js
import Vue from "vue";
import VueRouter from "vue-router";
import loginOrRegister from "@/views/loginOrRegister";
import success from "@/views/success.vue"
import index from "@/views/index.vue"
Vue.use(VueRouter);
const routes = [{
path: "/",
component: index,
name: "index",
meta: {
judge: true //判断登录状态
},
children: [{
path: "/loginOrRegister",
component: loginOrRegister,
name: 'loginOrRegister'
},
{
path: "/success/:id", //添加id 防止刷新后丢失页面
component: success,
name: "success",
meta: {
judge: true //判断登录状态
},
},
]
},
]
let router = new VueRouter({
routes
})
export default router;
在mysql建好表后,创建数据库和操作语法的js文件
/db/db.js
module.exports = {
mysql: {
host: 'localhost',
user: 'root',
password: '123456',
port: '3306',
database: 'test'
}
}
/db/sqlMap.js
const sqlMap = {
user: {
//增
addUser: 'INSERT INTO users (name, password) VALUES (?,?)',
//删
deleteUser : 'DELETE FROM users WHERE id = ?',
//改
updateUser_name : 'UPDATE users SET name = ? WHERE id = ?',
updateUser_pw : 'UPDATE users SET password = ? WHERE id = ?',
//查
select: 'SELECT * FROM users WHERE name = ? ',
selectAll: 'SELECT * FROM users'
}
}
module.exports = sqlMap;
main.js
import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import 'element-ui/lib/theme-chalk/display.css'
import App from './App.vue'
import router from './router'
Vue.use(ElementUI)
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
render: h => h(App)
})
以上就把项目的基本构架搭好啦!
2.前端
界面样式很简单,省略
顶栏 /views/navigation.vue:
<template>
<div class="top-box">
<div class="tag" v-show="!islogin">
<router-link :to="{name : 'loginOrRegister'}">
<el-button class="button" type="primary">登录/注册</el-button>
</router-link>
</div>
<div class="tag" v-show="islogin">{{name}}</div>
<div class="tag" v-show="islogin">
<el-button class="button" type="primary" @click="exit">退出登录</el-button>
</div>
</div>
</template>
<script>
export default {
name: "navigation",
data() {
return {
name: "",
islogin: false //记录登录状态
};
},
mounted() {
this.enter(); //页面发生变化时,查看状态
this.$router.beforeEach((to, from, next) => {
/* 路由发生变化时相应变化 */
if (to.meta.judge) {
this.enter();
}
next();
});
},
methods: {
enter() {
let that = this;
if (
window.sessionStorage.getItem("done") != undefined &&
window.sessionStorage.getItem("done") == "login"
) {
that.islogin = true;
that.name = window.sessionStorage.getItem("user");
}
else if( window.sessionStorage.getItem("done") == "register"){
console.log("注册成功!")
}
else
that.islogin = false
},
exit() {
window.sessionStorage.removeItem("done");
window.sessionStorage.removeItem("user");
this.$router.push("/");
}
}
};
</script>
/views/index.vue: (首页,固定顶栏,router-view包含的是路由页面。)
<template>
<div>
<el-container class="container">
<el-header class="top">
<navigation></navigation>
</el-header>
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</div>
</template>
<script>
import navigation from "./navigation.vue";
export default {
name: "index",
components: { navigation }
};
</script>
登录注册页面。 这里把ajax包装起来了,记录登录状态用的是sessionStorage。实际开发更多的是用axios+token
responseText为后端返回的信息,前端根据不同的信息反馈用户
/views/loginOrRegister.vue:
<script>
import { Message } from "element-ui";
export default {
name: "loginOrRegister",
data() {
return {
name: "",
pw: ""
};
},
mounted() {
//侦测登录/注册后的状态
this.watching();
},
methods: {
// 封装的ajax方法
ajax(method, url, val) {
// 方法,路径,传送数据
let that = this;
let name = this.name;
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
Message(xhr.responseText);
if (xhr.responseText == "登录成功") {
window.sessionStorage.setItem("user", name);
window.sessionStorage.setItem("done", "login"); //记录操作为登录
} else if (xhr.responseText == "注册成功") {
window.sessionStorage.setItem("user", name);
window.sessionStorage.setItem("done", "register"); //记录操作为注册状态
}
that.watching();
} else {
console.log("Request was unsuccessful: " + xhr.status);
}
}
};
xhr.open(method, url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(val);
},
login() {
let data = "name=" + this.name + "&" + "pw=" + this.pw;
this.ajax("POST", "http://127.0.0.1:3021/login", data);
},
register() {
let data = "name=" + this.name + "&" + "pw=" + this.pw;
this.ajax("POST", "http://127.0.0.1:3021/register", data);
},
watching() {
if (window.sessionStorage.getItem("done") != undefined) {
let status = window.sessionStorage.getItem("done");
if (status == "login")
this.$router.push({
name: "success",
params: {
id: "1"
}
});
else if (status == "register")
this.$router.push({
name: "success",
params: {
id: "0"
}
});
}
}
}
};
</script>
登录、注册成功后的页面。
/views/success.vue
<template>
<div>
<el-container>
<el-main>
<div class="messageBox">
<span>欢迎用户</span>
<span>{{name}},</span>
<span>{{msg}}</span>
</div>
</el-main>
</el-container>
</div>
</template>
<script>
import { Message } from "element-ui";
export default {
name: "home",
data() {
return {
name: "",
msg: ""
};
},
created() {
if(window.sessionStorage.getItem("done")){
//1为登录成功界面,0位注册成功界面
if (this.$route.params.id == "1")
this.msg = "登录成功!"
else if (this.$route.params.id == "0")
this.msg = "注册成功!"
this.name = window.sessionStorage.getItem("user");
window.sessionStorage.removeItem("done") //用完就删除
}
else
this.$router.push("/");
},
methods: {}
};
</script>
3.后端:
(由于就两个接口,这里都写在同一文件了)
src/service/http.js
let verify = require('../model/register.js')
let http = require('http');
let qs = require('querystring');
let models = require('./db/db')
let mysql = require('mysql')
let url = require("url")
let sql = require('./db/sqlMap')
let server = http.createServer(function (req, res) {
//连接数据库
let connection = mysql.createConnection(models.mysql)
connection.connect()
//获取前端代码发来的路由地址
let pathName = url.parse(req.url).pathname;
//接受数据
let body = '' // 一定要初始化为"" 不然是undefined
req.on('data', function (data) {
body += data;
})
req.on('end', function () {
res.writeHead(200, { // 响应状态
'Content-Type': 'text/html; charset=utf-8', // 响应数据类型
'Access-Control-Allow-origin': '*',//允许跨域访问
'Access-Control-Allow-Credentials': 'true',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
})
//解析、封装参数
let params = [qs.parse(body).name, qs.parse(body).pw]
if (pathName == '/register') {
//注册
let addUser = sql.user.addUser
let selectAll = sql.user.selectAll
connection.query(selectAll, params, function (err, result) {
if (err) {
console.log(err)
return;
} else {
//验证
let cb = verify(qs.parse(body).name, qs.parse(body).pw)
if (cb.result) {
let flag = false
result.forEach((item) => {
if (qs.parse(body).name == item.name)
flag = true
})
if (flag) {
res.write("用户名已被占用")
res.end()
connection.end()
} else {
connection.query(addUser, params, function (err) {
if (err) {
console.log(err)
res.write("出现错误,注册失败")
res.end()
connection.end()
return
} else {
res.write("注册成功")
res.end()
connection.end()
}
})
}
} else {
res.write("注册失败," + cb.message)
res.write
res.end()
connection.end()
}
}
})
} else if (pathName == '/login') {
let select = sql.user.select
//登录
connection.query(select, qs.parse(body).name, function (err, result) {
if (err) {
console.log(err)
res.write('请求失败')
res.end()
connection.end()
return
} else {
if (!result[0])
res.write('无此用户')
else if (result[0].password == qs.parse(body).pw) {
res.write('登录成功')
} else
res.write('用户名或密码错误')
res.end()
connection.end()
}
})
}
})
})
//监听的端口,要与前端ajax发送到的端口一致
server.listen(3021)
表单验证
/model/register.js
module.exports = function(name, pw){
let callback = {
result: false,
message:''
}
const reg = new RegExp(/^(?![^a-zA-Z]+$)(?!\D+$)/)
if(name == ''|| name == null)
callback.message = '请填写用户名'
else if( pw == '' || pw == null)
callback.message = '请填写密码'
else if ( name.length < 3)
callback.message = '用户名不得小于三个字符'
else if ( pw.length < 6 || pw.length >= 16)
callback.message = '密码长度6~16个字符'
else if (!reg.test(pw))
callback.message = '密码需包含数字和字母'
else{
callback.message = '用户名和密码合法!'
callback.result = true
}
return callback
}
//注册时检测合法性
end!
作为刚刚入门的小白,一直卡在前后端交互这一块,在学习了网上的很多碎片化知识后,自己总结并动手完成了这个基本的登录注册页面。 页面逻辑和运用的技术栈比较简单,但是五脏俱全。重在理解前后端交互和这种开发模式,等见识广后就在此基础上改进