Vite2.0+ElementPlus+Koa2+Mongo全栈开发通用后台系统Vue3
前言
当前基于NodeJs框架的全栈工程实践非常之火,作为一个很长时间未接触代码的前程序猿。一直有点手痒痒,想尝试一下这种全新的编程体验,于是就重新开始了填坑的不归之路。
这一套框架是基于现在的前后台分离的指导原则来做的:
当然,我没有那么多的服务来玩,真正的物理部署的话,所有的server都在同一台服务器上。
在华为云上租了一台ECS服务器,在自己的办公电脑上装上一个虚拟机,基本上就OK了。
ECS和虚拟机的linux版本均为:Ubuntu 16.04版本
我也没打算做出个什么系统了,正好有朋友说是让我帮忙做一个识别手写体的一个小程序,可以在他手机上访问,就寻思用这个架构做一个了,从前端上传图像,发送到百度AI的接口做一个识别就可以了。先从登录开始:
登录的数据流程是这样的:
二. 准备工作
nodejs安装
VUE和EXPRESS都是基于nodejs运行环境的。所以,第一步就是安装nodejs。
直接登录官网,选择版本号和运行环境,复制链接地址。然后就是一系列的配置动作了。
wget URL
xz -d XXXXX.tar.zx
tar xf XXXXX.tar
vim ~/.bashrc
export PATH=XXXXX/bin:$PATH //增加到.bashrc的最后,后续就可以直接执行node和npm命令了
- 1
- 2
- 3
- 4
- 5
配置npm仓库
vim ~/.npmrc //后面三行为.npmrc里面的内容
registry=https://registry.npm.taobao.org/
prefix=/data/nodejs/node_global
cache=/data/nodejs/node_cache
- 1
- 2
- 3
- 4
也可以直接使用命令:
npm config set registry https://registry.npm.taobao.org/
npm config set cache /data/nodejs/node_cache
npm config set prefix /data/nodejs/node_global/
- 1
- 2
- 3
后面这两行参数是将npm install -g的所有依赖包统一安装到一个地方。
把/data/nodejs/node_global/bin下放到PATH环境变量中
source ~/.bashrc
export PATH=/data/nodejs/node_global/bin:$PATH //添加到最后,后续执行vue,webpack命令方便一点
- 1
- 2
安装GIT
sudo apt-get install git
mkdir -p /projects
vue init wepack front_sys //项目名随便起的,这一步是在第三部分创建的,因为文章结构的原因放到这里了。
cd /projects/front_sys
git init
git config --global user.name "xx"
git config --global user.email "xx"
git add .
git commit -m "xxx"
git remote add origin "xxxx" //在网上找一个代码管理的,保存自己的代码做个存档,我用的是码云
git push -u origin master
express backend_sys //项目名随便起的,这一步是在第四部分创建的,因为文章结构的原因放到这里了。
git init
git config --global user.name "xx"
git config --global user.email "xx"
git add .
git commit -m "xxx"
git remote add origin "xxxx" //在网上找一个代码管理的,保存自己的代码做个存档,我用的是码云
git push -u origin master
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
把代码先备份好,后续部署啊什么的就都方便了。
安装mongodb
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-4.2.6.tgz
tar zxvf mongodb
vim ~/.bashrc
export PATH=XXXXX/bin:$PATH //增加到.bashrc的最后
mkdir -p /data/db //如果你的数据库目录不是/data/db,可以通过 --dbpath 来指定
- 1
- 2
- 3
- 4
- 5
然后直接执行(加&是表示后台启动,可以指定 fork 参数):
mongod &
- 1
就可以把数据库启动了。
执行:
mongo
- 1
就可以操作数据库了。
mongodb这样启动是单机模式,也就是只有localhost本机才能访问,要对外提供服务的话,还需要创建用户。在配置用户前,我们先配置一下mongodb的服务端:
创建一个配置文件:mongodb.conf,这个文件是可以随意放的,当然一般是有一定的规范的,我直接放在和/data/db下。
增加几个配置参数:
auth=true #开启认证模式
fork=true #后台运行
dbpath=XXXX #数据存放目录
logpath=xxxx #日志文件,这里一个大坑,我理解的也是一个目录,结果这里是要配置一个文件,而不是目录!!导致我填了半天坑,参考这篇文章:https://www.jb51.net/article/109091.htm
bind_id = 0.0.0.0 #全部IP可以访问,好像有一个新的参数bind_id_all,没试过
- 1
- 2
- 3
- 4
- 5
配置完后,直接执行mongod -f /data/db/mongodb.conf就可以启动了。
此时,通过mongo还是可以登录进来,但是执行show dbs就看不到任何信息了。
创建mongodb用户
mongo
> use xxxdb
switched to db xxxdb
> db
xxxdb
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
可以看到,我们刚创建的数据库 xxxdb并不在数据库的列表中, 要显示它,我们需要向 xxxdb数据库插入一些数据就可以了。
创建用户:
mongo
> use xxxdb //先use一下,不先use一下的话,这个账户会被create到test数据库中,后续通过URL就会连接不到,这个坑后续需要再研究下mongodb的认证机制。这个话题有点大,后续再说
> db.createUser({user: 'z', pwd: 'z', roles: [{role:'dbOwner', db: 'xxxdb'}]})
- 1
- 2
- 3
执行完之后会出现Successful的字样,就是创建成功了。可以退出重新登录一下。
mongo
> use xxxdb
> show tables //会提示错误
> db.auth('z', 'z')
> show tables //显示当前数据库下的documents,当然前提是之前建好了。
- 1
- 2
- 3
- 4
- 5
到这一步,基本上准备工作就做好了。
三. vue部分
我对于VUE的理解,最重要的就是可以解决网页中元素(element)和数据的双向绑定关系,之前的jQuery在有数据更新的时候,需要各种getElement,然后将相应的数据更新过去,很是麻烦。然后router相当于是MVC模式里的Controller。
VUE可以直接通过
script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"
- 1
的方式直接引用,但是nodejs的运行环境里直接有vue-cli这个脚手架工具,直接帮你创建一个vue的项目上下文,更加方便一点,我是为了学习的目的,所以直接使用vue-cli工具来搭建。
安装vue脚手架、webpack
npm install -g vue
npm install -g vue-cli
npm install -g webpack
- 1
- 2
- 3
这里提一下,在前面配置npm工具的时候的那几个参数就起作用了,在/data/nodejs/node_global/下会出现bin和lib两个文件夹,bin是执行文件,lib下会出现node_modules目录,里面把安装的模块分门别类放好。
安装完成后,使用脚手架工具创建项目
cd /projects
vue init webpack front_sys //会有几个问题需要你选择,我是一路按回车过去的。后续再慢慢研究
cd front_sys
npm start
- 1
- 2
- 3
- 4
这样就可以直接启动项目了,就可以看到前端服务已经跑起来了。
VUE的项目结构网上一搜一大把,就不放在这了。
修改界面
我就从登陆界面开始,图片懒得改了,增加两个输入框,两个按钮(体验一下就好)。
修改项目目录下src/components/HelloWorld.vue
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<div class="input_text">
<p>username: <input type="text" name="username" v-model="username" /></p>
<p>password: <input type="password" name="password" v-model="password" /></p>
</div>
<div><p color='red'>{{ result }}</p></div>
<div class="button">
<input type="button" name="login" value="Login" v-on:click="login()" />
<input type="button" name="clear" value="Clear" v-on:click="clear()" />
</div>
</div>
</template>
<script>
import axios from 'axios'
import qs from 'qs'
export default {
name: 'HelloWorld',
data () {
return {
msg: 'Welcome to reports App',
username: '',
password: '',
result: ''
}
},
methods: {
login: function () {
console.log(this.username)
var param = {'username': this.username, 'password': this.password}
axios.post('http://localhost:3000/users/login', qs.stringify(param))
.then(res => {
console.log(res.data)
if (res.data === 'wrong') {
this.result = 'please re-input your username and password'
}
})
.catch(function (error) {
console.log(error)
})
},
clear: function () {
this.username = ''
}
}
}
</script>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
几个改动点:
1. 属性绑定:v-bind:value和v-model,v-bind:value只是使用变量的值,修改标签中的值不会影响变量。而v-model是双向绑定。
2. 事件绑定:v-on:click绑定vue对象里面methods里的方法。
3. 使用axios做http请求的处理
这里肯定会碰到的问题就是跨域的问题,会到文章的最前面,前后台是分离的,那么基于浏览器的同源策略,请求资源的域与登录请求的域肯定不是同源的,那么就会存在跨域的问题。
跨域问题在http请求的两端都要做一些配置,在上面的代码中,为了处理跨域的问题,就只有在post()函数中,引入qs包,使用qs.stringify(param),将需要发送的post请求中的数据处理一下。至于为什么只要处理一下就可以解决跨域的问题,现在还不知道,后续针对跨域的整个话题再去研究一下,这篇文章只是记录快速搭建过程。
四. EXPRESS部分
后台服务器就是两个任务:
- 响应前端过来的http请求,一般为post请求。
- 与数据库交互
nodejs运行环境下,可以搭建http服务器并与数据库交互的框架有很多,express,koa,egg等。我挑了其中的express框架。我理解express是nodejs技术栈里面的struts。做http请求与action之间的映射Controller。
在nodejs框架下安装express:
npm install -g --save express
npm install -g --save express-generator
- 1
- 2
生成项目(对应到第二步的git部分):
cd /projects
express backend
cd backend
npm start
- 1
- 2
- 3
- 4
就可以将后台的服务跑起来了。
添加post请求响应
在router目录的user.js文件中添加(这里对应前端axios代码中的url地址 localhost:3000/user/login):
router.post(’/login’, function(req, res, next) {
console.log(req.body.username);
console.log(req.body.password);
var result = validate.authLogin(req.body.username, req.body.password);
console.log("abcd " + result);
res.header('Access-Control-Allow-Origin', '*')
if(result == 0) {
res.send('ok');
}
else {
res.send('wrong');
}
// res.send('ok');
})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
解决跨域问题
1. 在响应中添加header字段
res.header('Access-Control-Allow-Origin', '*') //这一句的意思是配合浏览器一起解决跨域问题,具体的描述网上也一堆。
- 1
2. 引入body-parser包
因为我是使用post请求来发送数据,因此请求的数据只能在请求体中,因此需要在后台引入body-parser包,修改根目录下的app.js:
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
- 1
- 2
- 3
引入这个包之后,在user.js中才能直接使用req.body.username这样的语句来直接访问请求体中的数据。
3. 引入cors包
解决跨域需要再引进cors包:
var cors = require('cors');
app.use(cors({
origin:['http://localhost:8080'],
method:['GET','POST'],
allowHeaders:['Content-Type', 'Authorization']
}));
- 1
- 2
- 3
- 4
- 5
- 6
改了这三个地方之后,前端的那个post请求就可以抵达后台并正确响应,前端也可以顺利的拿到这个响应数据了。
4. 引用public里面的内容
刚开始不太会引用express框架里面的各个文件,需要增加一个验证用户名/密码的函数,在public/javascripts目录下创建了一个validate.js
validate = {
authLogin(username, password) {
console.log("abcd" + username);
if(username != 'z') {
return 1;
}
return 0;
}
}
module.exports = validate;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
我的理解是validate = {} 定义了一个模块或者是类之类的东西,然后使用module.exports导出到整个项目。在项目其他地方就可以直接使用
valiedate.authLogin
- 1
至于import,export,require之间的关系,好像和JS的规范有关,后续再看吧。
访问mongodb
const mongoClient = require('mongodb').MongoClient;
const mongoUrl = "mongodb://z:z@localhost:27017/reports"
mongoClient.connect(mongoUrl, function(err, db) {
if (err) {
console.log(err);
throw err;
}
console.log("connected!");
const dbo = db.db("reports");
dbo.collection("users").find({}).toArray(function(err, result) {
if (err) {
throw err;
}
console.log(result);
db.close();
});
db.close();
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
mongodURL变量的格式为:mongodb://username:password@address:port/dbname
对应第二部分里面创建的用户。
在前面的validate函数中调用这个方法,基本上整个流程就是通的了。
五. 下一步
这篇文章在于记录最最基本的框架搭建,让自己有一个基本的理解,不进行深入问题的研究。相当于新框架中的HelloWorld程序吧。
基于上面的描述,下一步要了解的应该是下面两个问题:
- 跨域的问题,这个话题我觉得可以单独拉出来研究,后续再更新相关的内容
- JS模块规范,import,export,require的演进关系