一、vue 项目搭建
1、创建 vue 项目
vue create vue-element
说明:创建过程中可以选择路由,也可也可以不选择,可以通过 npm install 安装
vue 项目目录结构
说明:api 为自己创建的文件夹,router 选择路由模块会自动创建
router下的index.js文件(配置路由的文件)
import { createRouter, createWebHashHistory } from 'vue-router'
const routes = [
{
path: '/', //路由路径
name: 'login',
component: () => import(/* webpackChunkName: "about" */ '@/views/login.vue')//访问的页面
},
]
// 创建路由
const router = createRouter({
history: createWebHashHistory(),
routes
})
// 导出路由
export default router
views下的 login.vue
<template>
<div class="content">
<div class="login">
<span class="font">智慧车库管理</span>
<div>
账 号:<el-input
v-model="user.account"
style="width: 240px"
placeholder="请输入账号"
/>
</div>
<div style="margin-top: 20px">
密 码:<el-input
v-model="user.password"
style="width: 240px"
placeholder="请输入密码"
type="password"
show-password
/>
</div>
<div class="register">
<div>
<span>注册账号</span>
</div>
<div>
<span>验证码登录</span>
</div>
</div>
<div @click="login">
<el-button type="success" round size="large" class="loginbut">登录</el-button>
</div>
</div>
</div>
</template>
<script setup>
import { reactive , getCurrentInstance} from "vue";
const user = reactive({ account: "", password: "" });
const {proxy} = getCurrentInstance()
const login = async() => {
console.log(proxy.$urls.m().login);
const obj = {account:user.account,password:user.password}
const res = await new proxy.$request(proxy.$urls.m().login,obj).modepost()
};
</script>
<style scoped>
.content {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: aliceblue;
}
.login {
display: flex;
background-color: #ffffff;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
border-radius: 5px;
transition: transform 0.3s ease;
width: 600px;
height: 400px;
flex-direction: column;
align-items: center;
}
.login:hover {
transform: translateY(-10px); /* 鼠标滑过时向上浮动10px */
}
.font {
font-size: 24px;
font-family: Arial, Helvetica, sans-serif;
margin-bottom: 50px;
margin-top: 30px;
}
.register {
width: 50%;
display: flex;
justify-content: space-between;
margin-top: 30px;
}
.loginbut {
width: 200px;
margin-top: 40px;
}
</style>
main.js 中全局引入路由
import { createApp } from 'vue'
import App from './App.vue'
import router from './router' // 引入路由
import ElementPlus from 'element-plus' // 引入element,引入之前需要安装 参考element官方网站 (npm 等方式安装即可)
import 'element-plus/dist/index.css' // 引入element
import zhCn from 'element-plus/es/locale/lang/zh-cn' // element 国际化
const app = createApp(App);
app.use(router); // 使用路由
app.use(ElementPlus, {locale: zhCn,}); // 国际化
// 请求地址
import urls from './api/api.js'
app.config.globalProperties.$urls = urls
// 请求方法
import request from './api/request'
app.config.globalProperties.$request = request
app.mount('#app'); //挂载,app 在public下的index.html
App.vue 文件内容
<template>
<router-view/> // 路由页面显示位置
</template>
<script>
</script>
<style>
</style>
1、请求封装
1.1、axios 安装
cnpm install axios --save
1.2 api 封装(面向对象封装)
在 api 文件夹中创建 api.js。文件内容如下
const url = "http://localhost:8080"; // 基础url
const urls = class {
static m() {
const login = `${url}/login`; // 模板语法
return {
login // 导出 login 地址
}
}
}
export default urls // 暴露 urls
在 api 下创建 header.js 。内容如下
import axios from "axios"; //导入 axios
import {ElMessageBox } from 'element-plus' // 局部引入 element 弹框(虽然在main.js中已经全局引入,但是这里是js文件,并不是 vue 文件,所有要导入)
//创建 axios 全局配置
let instance = axios.create({
responseType: "json", // 期望后端返回的数据类型 json
headers: { "Content-Type": "application/json" },// 请求头中添加上传给服务器的数据类型 json
});
// http 拦截,请求发出之前
instance.interceptors.request.use(
(config) => {
let token = localStorage.getItem("token");//缓存中获取token
if (token) {
config.headers.Authorization = token; // 请求头中携带 token
}
return config;
},
(err) => {
return Promise.reject(err);
}
);
// http 拦截 ,请求发出之后
instance.interceptors.response.use(
(response) => {
return response;
},
(error) => {
if(error.response){
let ERRS = error.response.status
let MSG = error.response.data.data
let errdata = ERRS == 401 ? MSG : '服务器打盹啦'
switch(ERRS) { // 401 时特别处理 ,没有权限
case '401':
ElMessageBox.alert('没有权限', '提示', {
confirmButtonText: '好的',
type: 'error',
})
.then(res => {})
.catch(err => {})
break;
}
}
return Promise.reject(error.response.data)
}
)
export default instance
在 api 下创建 request.js 文件,文件内容如下
import instance from "./header"; // 引入 header.js 文件,instance 就是我们在 header.js 中暴露出的 axios 实例
const request = class { // 创建一个请求类
constructor(url, arg) { // 构造器赋值
this.url = url; // url
this.arg = arg; // 参数
}
modepost() { // 创建 post 请求
return new Promise((resolve, reject) => {
instance.post(this.url, this.arg)
// 成功回调
.then( res => {
resolve(res);
})
// 失败回调
.catch( err => {
reject(err)
})
});
}
// 创建 get 请求
modeget() {
return new Promise((reject,resolve) => {
instance.get((this.url))
// 成功回调
.then(res => {
resolve(res)
})
// 失败回调
.catch(err => {
reject(err)
})
})
}
}
export default request // 暴露
这三个文件创建完成之后,我们可以回过头去看 main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router' // 引入路由
import ElementPlus from 'element-plus' // 引入element,引入之前需要安装 参考element官方网站 (npm 等方式安装即可)
import 'element-plus/dist/index.css' // 引入element
import zhCn from 'element-plus/es/locale/lang/zh-cn' // element 国际化
const app = createApp(App);
app.use(router); // 使用路由
app.use(ElementPlus, {locale: zhCn,}); // 国际化
// 请求地址
import urls from './api/api.js'
app.config.globalProperties.$urls = urls
// 请求方法
import request from './api/request'
app.config.globalProperties.$request = request
app.mount('#app'); //挂载,app 在public下的index.html
主要看这里
// 请求地址
import urls from './api/api.js'
app.config.globalProperties.$urls = urls //全局配置请求地址
// 请求方法
import request from './api/request'
app.config.globalProperties.$request = request // 全局配置请求方法
然后再去看 login.vue 中的使用,这里我只拿过来 js 部分
<script setup>
import { reactive , getCurrentInstance} from "vue";
const user = reactive({ account: "", password: "" });
const {proxy} = getCurrentInstance() //对象展开获取 proxy
const login = async() => {
const obj = {account:user.account,password:user.password} // 封装请求参数
const res = await new proxy.$request(proxy.$urls.m().login,obj).modepost() // 创建 request 实例并调用 modepost() 方法发送请求
};
</script>
到这里,vue 项目的基本搭建已经完成
二、spring boot 项目搭建
使用 idea 创建 springboot项目,导入web 依赖即可
项目结构
这里比较简单,不过都赘述,
看一下测试接口(LoginController)
@Slf4j // 日志注解
@RestController // 表示是一个controller,并且会返回json 数据,相当于 @Controller 和 @ResponseBody 组合
@RequestMapping("/login") // 请求地址 /login ,支持所有方式的请求
@CrossOrigin(origins = "http://localhost:8082") // 跨域解决,允许本机8082程序访问(后续会统一处理)
public class LoginController {
@PostMapping // 接受 /login 下的 post 请求
public String Login(@RequestBody LoginDTO loginDTO){ // @RequestBody 接受请求体中的 json 数据并解析为 LoginDTO 对象
log.info(loginDTO.toString()); // 日志打印解析后的对象
return "";
}
}
LoginDTO 在controller 下的 dto 下,内容如下
@Data
@AllArgsConstructor
@NoArgsConstructor // 这三个都是 Lombok 注解,简化开发 ,自动生成getter,setter 构造器等
public class LoginDTO {
private String account;
private String password;
}
三、spring boot 日志输出配置
在 resources 下创建
logback-spring.xml
写入以下内容
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/myapp.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天滚动,并保留30天的日志 -->
<fileNamePattern>logs/archived/myapp-%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
<maxHistory>30</maxHistory>
<!-- 当日志文件达到10MB时,进行压缩并滚动 -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<root level="info">
<appender-ref ref="ROLLING" />
</root>
</configuration>