什么是前后端联调
前后端联调呢主要是说后台写接口供前端调用。
在这整个过程中,涉及到以下几点知识点。 包括:
- koa2的知识点
- vue3的知识点
- 跨域问题
- axios的使用
- postman(airpost)软件
第一部分:环境搭建
vue3
首先是vue3 + vue-router + vuex的环境。我们用vue ui生成项目,会用vue的同学对这块应该很熟了。
// 集成终端输入
vue ui
// 启动项目
npm run serve
首先
其次
然后
再然后
因为vue ui生成的vue项目包含vuex,vue-router,less/scss这些都是可以自己选的(如下图)
完成之后点击创建即可
koa2环境
前端项目构建好了,就开始构建我们的后端服务。
首先在你桌面或者随便一个地方新建一个目录,用来搭建基于koa的web服务。
在这里,我们不妨给这个目录起名为koa-demo。
然后执行:
// 进入目录
cd koa-demo
// 生成package.json
npm init -y
// 安装以下依赖项
npm i koa
npm install mongoose
npm install koa-body
安装好koa和mongoose(是一个数据库)以及koa-body,环境就算搭建完成了。
第二部分:示例开发
搭建环境是为了使用,所以我们立马来写一个demo出来。 demo开发既是一个练习如何在开发环境中写代码的过程,反过来,也是一个验证环境搭建的对不对、好不好用的过程。
后端接口开发
本例中,后端我们只提供一个用户列表服务,就是给前端提供一个返回json数据的接口。代码中包含注释,所以直接上代码。
app.js文件
// app.js文件
//引入koa框架
let Koa = require('koa');
//引入vue路由
let Router = require('koa-router');
//引入数据库
const mongoose = require('mongoose')
const KoaBody = require('koa-body')
//由于我们要使用数据库做数据持久化的处理所以得线连接数据库
// 此处代码需要去官网复制
mongoose.connect('mongodb://localhost/admin');
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
// we're connected!
console.log('我们已经链接上本地数据库了!!');
});
//实例化koa框架
const app = new Koa();
//实例化路由
const router = new Router();
// 用户列表的请求
//async await 是异步请求
router.get('/list', async ctx=>{
let userList = await User.find()
//当数组的长度大于0的时候
if(userList.length>0){
let users = []
userList.forEach(item=>{
let obj = {
id:item._id,
username:item.username,
createData:item.createData
}
//把数据存到数组里面去
users.push(obj);
})
ctx.body={
msg:'请求用户列表成功',
code:1,
data:users,
}
}
})
//使用koa
app.use(KoaBody())
// 将koa和两个中间件连起来
app.use(router.routes()).use(router.allowedMethods());
// 监听3000端口
app.listen(3000, () => {
console.log("我们正在监听端口号为3000的koa服务");
});
mongose官网(mongoosejs.net/docs/index.…)
然后我们是用以下命令将服务启动
npm run start
测试接口是否良好
使用postman或者Airpost(都是软件)即可
前端调用后端接口示例
为突出重点,排除干扰,方便理解。我们的前端就写一个组件,组件是一个内容展示区域,拿到后端返回的数据以后,将其在组件的这块区域显示出来。
首先我们看组件文件吧
<template>
<div class="users">
<div class="users__title">用户管理</div>
<el-table :data="tableData" style="width: 100% margin-top:10px" border="true">
<el-table-column label="Id" width="auto" prop="id"> </el-table-column>
<el-table-column label="用户名" width="auto" prop="username"> </el-table-column>
<el-table-column label="创建时间" width="auto">
<template #default="scope">
<el-icon>
<timer />
</el-icon>
<span style="margin-left: 10px">{{ timeFormatter(scope.row.createData) }}</span>
</template>
</el-table-column>
<el-table-column label="操作">
<template #default="scope">
<el-button size="small" @click="handleEdit(scope.row)">重置密码</el-button>
<el-button size="small" type="danger" @click="handleDelete(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script setup>
//引入api接口
import { getUserList, } from '@/api';
//引入vue3的方法
import { onMounted, reactive, getCurrentInstance, computed, ref } from 'vue';
import { Timer } from '@element-plus/icons'; // svg图标
const tableData = reactive([]);
// 创建时间
const { proxy } = getCurrentInstance();
const timeFormatter = (time) => {
return proxy.$moment(time).format('YYYY-MM-DD hh:mm:ss');
};
//请求数据
const getList = () => {
//调用接口
getUserList(params)
.then((res) => {
//成功返回res
console.log(res);
})
.catch((err) => {
//失败返回err
console.log(err);
});
};
//监听
onMounted(() => {
getList();
});
</script>
<style lang="scss" scoped>
.users {
width: 95%;
background: white;
margin: 20px 0 0 20px;
&__title {
width: 100%;
font-size: 16px;
font-weight: bold;
height: 50px;
line-height: 50px;
padding-left: 20px;
}
.el-pagination {
width: 100%;
margin-top: 15px;
background: white;
}
}
</style>
非常简单,就不多解释了。 然后看我们的api文件。
//这里引入的是axios 请求
import http from '../utils/http';
export const getUserList = (data) => {
return http({
method: 'get',
url: '/users/list',
params: data
})
}
ok, 代码撸完了,获取后端数据之后是这样的。
说说axios
首先需要安装axios
npm i axios
import axios from 'axios'
2、建一个工具为utils的文件 里面可以适当做一些处理
import axios from 'axios';
import { ElNotification } from "element-plus"
import router from '@/router';
const http = axios.create({
baseURL: '/api',
});
// 添加请求拦截器
http.interceptors.request.use(function (config) {
// 这里获取一下token是为了做登录页面 拼接token的值
if (sessionStorage.getItem('token')) {
config.headers['Authorization'] = 'Bearer ' + sessionStorage.getItem('token')
}
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
http.interceptors.response.use(function (response) {
// 对响应数据。状态==200的时候返回data
if (response.status === 200) {
return response.data;
}
}, function (error) {
// 对响应错误直接在1.5秒以后弹出到login页面
if (error.response.status === 401) {
setTimeout(() => {
router.push({ path: '/login', query: { redirectURL: window.location.href } })
}, 1500)
}
return Promise.reject(error);
});
export default http
3、又会遇到跨域,在vue.config.js中修改,添加devServer项的配置:
devServer: {
open: true,
proxy: {
'/api': {
target: 'http://localhost:3000',
ws: true,
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
后记
这样就可以解决前端取后端数据跨域的问题一个是axios里面的baseURL的值需要注意,还有就是vue.config.js里面的拘数据以及这个文件名字,不要问我为什么要注意,自己体验以后就知道了
OK,以上就是全文了。 如果这篇文章使你有所收获,不胜荣幸。 欢迎点赞,以期能帮助更多同学!