最近这两天有点闲,通过自研学习了如何使用express框架搭建后台以及vue框架开发前端。express框架是用来搭建web服务,是nodejs的二次封装。vue就是前端框架。那么可以通过搭建express框架用来写接口,vue框架写页面用来调用接口,形成全栈的开发。
1、搭建express过程
使用 express的脚手架快速搭建:express-generator
首先安装express 和express-generator
npm install -g express,npm install -g express-generator(这是全局安装)
创建项目
express -e 目录
npm install 安装依赖
npm start 开启项目
安装后台热更新模块(这样方便开发,修改文件就不需要重启启动了,会热更新)
npm i nodemon --save(局部安装,下载到项目依赖,所以一定要进入项目目录里安装)
安装完成nodemon之后,需在package.json的**scripts**修改命令行:
"scripts": {
"start": "nodemon ./bin/www"
},
安装完成之后的项目结构目录
│ app.js
│ package-lock.json
│ package.json
│
├─bin
│ www
│
├─public
│ ├─images
│ ├─javascripts
│ └─stylesheets
│ style.css
│
├─routes
│ index.js
│ users.js
│
└─views
error.jade
index.jade
layout.jade
以上就是完成对express脚手架的安装啦~~ 端口号3000。
接下来介绍一下app.js:
app.use(express.static(path.join(__dirname, 'public'))); //静态托管,在搭建大前端时将页面放置public文件夹。因为我们是前后端分离模式,所以可以把这行代码注释了
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');//视图模板,在搭建大后端的时将模板放置views文件夹,因为我们是前后端分离模式,所以可以把这行代码注释了
2、搭建vue过程
通过@vue/cli脚手架完成前端的搭建,端口号是8081~~
安装@vue/cli,vue脚手架3
npm i @vue/cli
//可查看版本
@vue/cli -V
//创建项目
vue create 项目名
好啦~前后端的demo都已经完成了,那么现在要做的就是连接数据库,以及前端如何调用接口问题。这也是项目当中比较难的地方。
3、连接数据库的问题
(1)操作数据库
(2)下载数据库
(3) 安装navicat,用navicat操作管理数据库,点击连接,添加连接名(可随意)
连接数据库 填写数据库的ip以及用户名以及密码点击连接测试,连接成功可点确定。
(4)连接数据库,nodejs操作数据库写接口在项目中安装好mysql数据库驱动。
下载第三方包 mysql(相当于驱动包,依赖模块)
npm i mysql --save(项目依赖)
注意:安装mysql时最好是先cd到项目文件夹下,如果不这样的话必须全局安装,为避免无法找到mysql模块,还是在项目文件夹下安装较为保险。
//连接数据库的代码,新建sql文件夹,新建db.js文件
测试版本的连接数据库代码:
因为开发每一个接口都需要连接数据库,那么上面的代码就得在每个接口写一遍,为了不让代码冗余,进行封装。
let mysql=require('mysql');
module.exports=(option={},sql,callback)=>{
let host=option.host||'99.47.133.165'; //数据库所在的服务器的ip地址
let user=option.user||'root'; //用户名
let password=option.password||'3edc$RFV5tgb'; //密码
let database=option.database ||null //你的数据库名
let db=mysql.createConnection({
host:host,
user:user,
password:password,
database:database
}); //创建连接
if(!(typeof sql=='string')){
return ;
};
db.connect(); //打开连接
//数据库操作也是异步的
db.query(sql,(error,result)=>{
if(error){
console.log(error);
return;
}
callback(result);
})
//关闭连接
db.end();
}
前端提供一个页面:
<template>
<div class="login">
<div class="content">
<el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="账号" prop="age">
<el-input v-model.number="ruleForm.age"></el-input>
</el-form-item>
<el-form-item label="密码" prop="pass">
<el-input type="password" v-model="ruleForm.pass" autocomplete="off"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')">登录</el-button>
<el-button @click="resetForm('ruleForm')">注册</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
import axios from 'axios';
export default{
name:'loginPage',
data(){
var checkAge = (rule, value, callback) => {
if (!value) {
return callback(new Error('年龄不能为空'));
}
setTimeout(() => {
if (!Number.isInteger(value)) {
callback(new Error('请输入数字值'));
} else {
if (value < 18) {
callback(new Error('必须年满18岁'));
} else {
callback();
}
}
}, 1000);
};
var validatePass2 = (rule, value, callback) => {
if (value === '') {
callback(new Error('请再次输入密码'));
} else if (value !== this.ruleForm.pass) {
callback(new Error('两次输入密码不一致!'));
} else {
callback();
}
};
return {
ruleForm: {
pass: '',
age: ''
},
rules: {
pass: [
{ validator: validatePass2, trigger: 'blur' }
],
age: [
{ validator: checkAge, trigger: 'blur' }
]
}
};
},
methods:{
submitForm(){
this.$api.request({
methods:'get',
url:'/api/user/login',
// params:{
// age:this.ruleForm.age,
// password:this.ruleForm.password,
// }
}).then(res=>{
console.log(res)
}).catch(err=>{
console.log(err)
})
// axios.get('localhost:3000/user/login').then(res=>{
// console.log(res)
// })
},
resetForm(){},
}
}
</script>
<style lang="scss" scoped>
.login{
width: 100%;
height: 100%;
background: #ff14932e;
.content{
width: 400px;
height: 400px;
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
margin:auto;
}
}
</style>
后台express框架的app.js文件代码以及route文件夹下的users.js的代码
//在app.js写入如下代码行
app.use('/api/user/login', usersRouter); //路由导向
//在文件route->users.js处理路由
var express = require('express');
var router = express.Router();
var db=require('../sql/db.js');
router.get('/', function(req, res, next) {
console.log('dsdhh'); //如果调用成功就会打印
res.send();
});
module.exports = router;
前端通过请求调用接口,后台打印结果,说明数据调用成功。
其实在连调的这个过程当中,还真遇到坑
坑1、跨域问题
解决跨域问题:
后台做配置,在app.js入口文件写如下代码。一定要在路由导向之前写
app.all("*",(req,res,next)=>{
//设置允许跨域的域名,*代表允许任意域名跨域
res.header("Access-Control-Allow-Origin",'http://localhost:8081');//火狐,360本地开发需要具体写前端的端口看,这是一个坑。
res.header("Access-Control-Allow-Origin", "*");//谷歌浏览器写*就行
//允许的header类型
res.header("Access-Control-Allow-Headers", "X-Requested-With,Content-Type");Content-Type不加
//跨域允许的请求方式
res.header("Access-Control-Allow-Methods","DELETE,PUT,POST,GET,OPTIONS");
res.header("X-Powered-By","Express");
res.header("Content-Type","application/json;charset=utf-8");
res.header("Access-Control-Allow-Credentials",true)
// if (req.method.toLowerCase() == 'options')
// res.send(200); //让options尝试请求快速结束
// else
next();
})
坑2:
路由找不到,路由导向的path要和接口的path一致,但是在route文件夹下写接口是要重定向。代码如下:
var express = require('express');
var router = express.Router();
var db=require('../sql/db.js');
router.get('/', function(req, res, next) {
console.log('dsdhh');
res.send();
});
module.exports = router;
来源:oschina
链接:https://my.oschina.net/u/4401867/blog/4318248