SpringBoot与Vue前后端交互问题
在vue中找到vue.config.js文件中,加入下列代码:
const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ devServer: { port:8888,//修改前端应用的端口号(可以改为你想改的任意数字,不要与后端冲突就行) proxy: { // 配置代理,解决跨域问题 '/api': { target: 'http://localhost:8080', // 后端接口的基础 URL changeOrigin: true, // 是否改变请求头中的 Origin 字段 pathRewrite: { '^/api': '' // 将请求路径中的 '/api' 替换为空字符串,去除 '/api' 前缀 } } } } });
在后端创建CrosConfig文件,导入以下代码
package com.team.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CrosConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:8888/")//端口号需要修改为与前端vue.config.js中相对应的端口号 .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS") .allowCredentials(true) .maxAge(3600) .allowedHeaders("*"); } }
目录结构为
在前端和后端分别按照以上操作,即可完成前后端交互。
下面是一个示例:
首先创建vue项目
选择手动配置项目
选择Babel、Router、Linter和使用配置文件
配置选择
点击创建项目,创建完成。
将router文件夹下的index.js改为下列代码
import Vue from 'vue' import VueRouter from 'vue-router' import ShopView from '../views/ShopMenu.vue' Vue.use(VueRouter) const routes = [ { path: '/', redirect: "/shop" }, { path:'/shop', name:'shop', component:ShopView } ] const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }) export default router
安装element-ui和axios
npm install element-ui@2.15.3
npm install axios
在main.js中添加下列代码
import ElementUI from 'element-ui' import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI);
在views下创建ShopMenu.vue文件
<template> <div> <el-form :inline="true" :model="searchForm" class="demo-form-inline"> <el-form-item label="名称"> <el-input v-model="searchForm.name" placeholder="名称"></el-input> </el-form-item> <el-form-item label="地址"> <el-input v-model="searchForm.address" placeholder="地址"></el-input> </el-form-item> <el-form-item label="面积"> <el-input v-model="searchForm.size" placeholder="面积"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit">查询</el-button> </el-form-item> </el-form> <el-row> <el-button type="danger" plain @click="deleteByIds" style="float: left;">批量删除</el-button> <el-button type="primary" plain @click="dialogVisible = true" style="float: left;">新增</el-button> </el-row> <el-dialog title="新增门店" :visible.sync="dialogVisible" width="30%"> <el-form ref="form" :model="shopadd" label-width="100px"> <el-form-item label="门店名称"> <el-input v-model="shopadd.name"></el-input> </el-form-item> <el-form-item label="地址"> <el-input v-model="shopadd.address"></el-input> </el-form-item> <el-form-item label="面积"> <el-input v-model="shopadd.size" placeholder="(平方米)"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="addshop">确定</el-button> <el-button @click="dialogVisible = false">返回</el-button> </el-form-item> </el-form> </el-dialog> <el-table :data="tableData" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55"> </el-table-column> <el-table-column prop="name" label="门店名称" width="180"></el-table-column> <el-table-column prop="address" label="地点" width="180"></el-table-column> <el-table-column prop="size" label="面积(平方米)" width="180"> </el-table-column> <el-table-column align="center" label="操作"> <template slot-scope="scope"> <el-button type="primary" size="small" @click="editStore(scope.row.id)">编辑</el-button> <el-button type="danger" size="small" @click="deleteStore(scope.row.id)">删除</el-button> </template> </el-table-column> </el-table> <br> <el-dialog title="修改门店信息" :visible.sync="dialogVisible1" width="30%"> <el-form ref="form" :model="shopupdate" label-width="100px"> <el-form-item label="门店名称"> <el-input v-model="shopupdate.name"></el-input> </el-form-item> <el-form-item label="地址"> <el-input v-model="shopupdate.address"></el-input> </el-form-item> <el-form-item label="面积"> <el-input v-model="shopupdate.size" placeholder="(平方米)"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="updateshop">确定</el-button> <el-button @click="dialogVisible1 = false">返回</el-button> </el-form-item> </el-form> </el-dialog> <!-- 分页条 --> <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage" :page-sizes="[5, 10, 15, 20]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="totalCount"> </el-pagination> </div> </template> <script> import axios from 'axios'; export default { name: 'VueShop', data() { return { totalCount: 1000, // 当前页码 currentPage: 1, pageSize: 5, tableData: [ { name: '1', address: '北京市', size: '600', id: '' }, ], dialogVisible: false, dialogVisible1: false, searchForm: { name: "", address: "", size: "" }, shopadd: { name: "", address: "", size: "" }, shop: { name: "", address: "", size: "" }, shopupdate: { name: "", address: "", size: "" } } }, mounted() { this.onSubmit(); }, methods: { onSubmit() { const params = { name: this.searchForm.name || null, address: this.searchForm.address || null, size: this.searchForm.size || null, pageSize: this.pageSize, // 每页显示条数 page: this.currentPage // 当前页码 }; axios.get('http://localhost:8080/store/select', { params }) .then(response => { // 处理查询结果 console.log(response.data); this.tableData = response.data.rows; this.totalCount = response.data.total; }) .catch(error => { // 处理错误 console.error(error); }); }, logout() { this.$router.push({ path: "/login" }); }, deleteStore(id) { console.log(id); this.$confirm('此操作将删除该数据, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { axios.delete(`http://localhost:8080/store/${id}`) .then(response => { // 删除成功后的处理逻辑 console.log(response); this.$message.success('门店删除成功'); this.onSubmit(); // 在此处执行其他逻辑,例如重新加载员工列表等 }) .catch(error => { // 删除失败后的处理逻辑 this.$message.error('门店删除失败'); console.error(error); }); }).catch(() => { // 取消删除时的处理逻辑 this.$message.info('已取消删除'); }); }, editStore(row) { console.log(row); // 根据id从后端查询门店信息 axios.get(`http://localhost:8080/store/select/${row}`) .then(response => { console.log(response.data); // 将查询到的员工信息回显到编辑表单中 this.shopupdate = response.data; this.dialogVisible1 = true; // 打开编辑对话框 }) .catch(error => { console.error(error); }); }, addshop() { const params = { name: this.shopadd.name, address: this.shopadd.address, size: this.shopadd.size, }; // 发送添加门店请求 axios.post('http://localhost:8080/store/add', params) .then(response => { // 处理添加门店成功的逻辑 console.log('添加门店成功', response); // 关闭对话框 this.$message({ message: '恭喜你,添加成功', type: 'success' }); this.dialogVisible = false; // 清空表单数据 this.shopadd = {}; // 刷新员工列表等操作 // ... this.onSubmit(); }) .catch(error => { // 处理添加门店失败的逻辑 console.error('添加门店失败', error); // 显示错误提示等操作 this.onSubmit(); // ... }); }, deleteByIds() { const ids = this.multipleSelection.map(item => item.id); console.log(ids); this.$confirm('此操作将删除该数据, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { axios.delete(`http://localhost:8080/store/${ids.join(',')}`) .then(response => { // 处理删除成功的逻辑 console.log('删除成功', response.data); this.$message({ message: '恭喜你,删除成功', type: 'success' }); this.onSubmit(); }) .catch(error => { // 处理删除失败的逻辑 console.error('删除失败', error); }); }).catch(() => { this.$message.info('已取消删除'); }) }, updateshop() { const requestBody = { // 根据后端接口的定义,传递需要更新的门店信息 name: this.shopupdate.name, address: this.shopupdate.address, size: this.shopupdate.size, }; axios.put(`http://localhost:8080/store/update/` + this.shopupdate.id, requestBody) .then(response => { console.log(response); // 打印响应信息 this.dialogVisible1 = false; // 关闭编辑对话框 // 刷新表格数据等操作 this.onSubmit(); this.$message.success('门店信息更新成功!'); }) .catch(error => { console.error(error); // 打印错误信息 this.$message.error('门店信息更新失败,请重试!'); }); }, handleSizeChange(size) { // 处理每页显示条数变更事件 this.pageSize = size; // 这里可以重新调用查询接口获取当前页数据 // ... this.onSubmit(); }, handleCurrentChange(currentPage) { // 处理页码变更事件 this.currentPage = currentPage; // 这里可以重新调用查询接口获取当前页数据 // ... this.onSubmit(); }, handleSelectionChange(val) { this.multipleSelection = val; } } }; </script> <style lang="scss" scoped> </style>
后端用springboot创建
不会用springboot创建项目的可以看 2020版IDEA创建springboot项目
创建完项目后数据库的配置 在application.properties文件中添加如下代码
#数据库连接 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/scheduling spring.datasource.username=root spring.datasource.password=123456 #开启mybatis的日志输出 mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl #开启数据库表字段 到 实体类属性的驼峰映射 mybatis.configuration.map-underscore-to-camel-case=true
在pom.xml文件中导入lombok和pageHelper
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.4.2</version> </dependency>
后端目录结构
StoreController
package com.ysk.controller; import com.ysk.pojo.PageBean; import com.ysk.pojo.Result; import com.ysk.pojo.Store; import com.ysk.service.StoreService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @Slf4j @RestController @RequestMapping("/store") public class StoreController { @Autowired private StoreService storeService; @GetMapping("/select") public PageBean page(@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "5") Integer pageSize, String name, String address, Double size){ log.info("分页查询,参数:{},{},{},{},{}", page, pageSize,name,address,size); PageBean pageBean = storeService.page(page, pageSize,name,address,size); return pageBean; } @PostMapping("/add") public Result save(@RequestBody Store store){ log.info("新增门店,stuff:{}",store); storeService.save(store); return Result.success(); } //批量删除 @DeleteMapping("/{ids}") public Result delete(@PathVariable List<Integer> ids){ storeService.delete(ids); return Result.success(); } @GetMapping("/select/{id}") public Store getStoreById(@PathVariable Integer id) { // 在这里可以根据 userId 和 userName 进行身份验证或其他操作 // 假设 userService 提供了获取用户信息的方法 return storeService.getByStoreId(id); } @PutMapping("/update/{id}") public Result update(@PathVariable("id") Integer id,@RequestBody Store store){ Store existingEmp = storeService.getByStoreId(id); if (existingEmp != null) { existingEmp.setName(store.getName()); existingEmp.setAddress(store.getAddress()); existingEmp.setSize(store.getSize()); storeService.update(existingEmp); return Result.success(); } else { return Result.error("门店信息不存在"); } } @GetMapping("/data") public Store getDataByStore(@RequestParam("id") Integer id){ return storeService.getByStoreId(id); } }
StoreMapper
package com.ysk.mapper; import com.ysk.pojo.Store; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import java.util.List; @Mapper public interface StoreMapper { public List<Store> list(String name,String address,Double size); @Insert("insert into store(name,address,size) value (#{name},#{address},#{size})") public void insert(Store store); public void delete(List<Integer> ids); @Select("select * from store where id =#{id}") public Store getStuffById(Integer id); public void update(Store store); }
PageBean
package com.ysk.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; @Data @NoArgsConstructor @AllArgsConstructor public class PageBean { private Long total; private List rows; }
Result
package com.ysk.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor public class Result { private Integer code;//响应码,1 代表成功; 0 代表失败 private String msg; //响应信息 描述字符串 private Object data; //返回的数据 //增删改 成功响应 public static Result success(){ return new Result(1,"success",null); } //查询 成功响应 public static Result success(Object data){ return new Result(1,"success",data); } //失败响应 public static Result error(String msg){ return new Result(0,msg,null); } }
Store
package com.ysk.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public class Store { //店的id private Integer id; //用于展示的数据 private String name;//店的名字 private String address;//店的地址 //用于计算的数据 private Double size;//店的面积 private Double preDivisorValue;//开店前准备除数的权值 private Integer freePopulationNum;//店空闲时需要的人数 private Double aftDivisorValue;//关店后准备除数的权值 private Integer aftAddValue;//关店后准备加数的权值 private Integer prePrepareHourNum;//开店之前需要做几小时准备工作 private Integer aftPrepareHourNum;//关门之后需要做几小时准备工作 private Double passFlowDivisorValue;//人流量对应店员数的除数权值 }
StoreService
package com.ysk.service; import com.ysk.pojo.PageBean; import com.ysk.pojo.Store; import com.ysk.pojo.PageBean; import java.util.List; public interface StoreService { //分页查询 PageBean page(Integer page, Integer pageSize, String name, String address, Double size); //新增门店 public void save(Store store); //删除门店 public void delete(List<Integer> ids); public Store getByStoreId(Integer id); public void update(Store store); }
StoreServiceImpl
package com.ysk.service.Impl; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import com.ysk.mapper.StoreMapper; import com.ysk.pojo.PageBean; import com.ysk.pojo.Store; import com.ysk.service.StoreService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Slf4j @Service public class StoreServiceImpl implements StoreService { @Autowired private StoreMapper storeMapper; @Override public PageBean page(Integer page, Integer pageSize, String name, String address, Double size) { PageHelper.startPage(page,pageSize); List<Store> storeList = storeMapper.list(name,address,size); Page<Store> s = (Page<Store>) storeList; PageBean pageBean = new PageBean(s.getTotal(),s.getResult()); return pageBean; } @Override public void save(Store store) { storeMapper.insert(store); } @Override public void delete(List<Integer> ids) { storeMapper.delete(ids); } @Override public Store getByStoreId(Integer id) { return storeMapper.getStuffById(id); } @Override public void update(Store store) { storeMapper.update(store); } }
运行结果展示
新增
批量删除
修改
后端代码的地址
https://gitee.com/forget1204/2023-4-24
https://github.com/Yskkkkk/2023-4-24backend
前端代码的地址
本文作者:万事胜意k
本文链接:https://www.cnblogs.com/ysk0904/p/17349947.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步