前言
在现代化Web应用开发中,前后端分离架构已成为主流。本文将详细介绍如何使用Vue3作为前端框架,SpringBoot作为后端框架,实现一套完整的增删改查(CRUD)功能,包含分页查询、条件筛选等企业级特性。
技术栈介绍
前端:Vue3 + Element Plus + Axios
后端:SpringBoot + MyBatis-Plus
构建工具:Vite (前端) + Maven (后端)
一、环境准备与项目搭建
1.1 前端项目初始化
bash
复制
下载
npm init vue@latest vue3-springboot-crud cd vue3-springboot-crud npm install axios element-plus --save
1.2 后端项目搭建
使用Spring Initializr创建项目,添加以下依赖:
Spring Web
MyBatis Framework
Lombok
MySQL Driver
二、核心功能实现
2.1 跨域解决方案
前后端分离开发首要解决跨域问题,SpringBoot后端配置如下:
java
复制
下载
@Configuration public class CrossConfig { private static final long MAX_AGE = 24 * 60 * 60; @Bean public CorsFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); config.addAllowedOrigin("*"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); config.setMaxAge(MAX_AGE); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } }
2.2 前端Axios封装
javascript
复制
下载
import axios from "axios"; import { ElMessage } from 'element-plus' const http = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL, timeout: 50000 }) // 请求拦截器 http.interceptors.request.use(config => { config.headers['Content-Type'] = "application/json;charset=utf-8" const user = JSON.parse(localStorage.getItem("user") || '{}') if (user.token) { config.headers['Authorization'] = `Bearer ${user.token}` } return config }) // 响应拦截器 http.interceptors.response.use(response => { if (response.data.code !== 200) { ElMessage.error(response.data.message) } return response.data }, error => { ElMessage.error(error.message) return Promise.reject(error) }) export default http
三、分页查询实现
3.1 后端分页逻辑
java
复制
下载
@PostMapping("/list_page") public Result<PageResult<User>> listPage(@RequestBody PageQuery<User> query) { QueryWrapper<User> wrapper = new QueryWrapper<>(); if (StringUtils.isNotBlank(query.getEntity().getName())) { wrapper.like("name", query.getEntity().getName()); } int total = userMapper.selectCount(wrapper); PageHelper.startPage(query.getCurrentPage(), query.getPageSize()); List<User> list = userMapper.selectList(wrapper); return Result.success(new PageResult<>(total, list)); }
3.2 前端分页组件
vue
复制
下载
<template> <div class="pagination-container"> <el-pagination v-model:current-page="queryParams.currentPage" v-model:page-size="queryParams.pageSize" :page-sizes="[10, 20, 50, 100]" layout="total, sizes, prev, pager, next" :total="total" @size-change="handleQuery" @current-change="handleQuery" /> </div> </template> <script setup> import { reactive, ref } from 'vue' import http from '@/utils/request' const queryParams = reactive({ currentPage: 1, pageSize: 10, name: '' }) const total = ref(0) const tableData = ref([]) const handleQuery = async () => { const res = await http.post('/user/list_page', queryParams) tableData.value = res.data.list total.value = res.data.total } </script>
四、完整CRUD实现
4.1 新增数据
java
复制
下载
@PostMapping("/add") public Result<String> addUser(@RequestBody User user) { user.setCreateTime(LocalDateTime.now()); userMapper.insert(user); return Result.success("添加成功"); }
4.2 更新数据
java
复制
下载
@PostMapping("/update") public Result<String> updateUser(@RequestBody User user) { user.setUpdateTime(LocalDateTime.now()); userMapper.updateById(user); return Result.success("更新成功"); }
4.3 删除数据
java
复制
下载
@PostMapping("/delete") public Result<String> deleteUser(@RequestBody List<Long> ids) { if (ids != null && !ids.isEmpty()) { userMapper.deleteBatchIds(ids); } return Result.success("删除成功"); }
五、前端界面优化
5.1 表格与表单组件
vue
复制
下载
<template> <div class="app-container"> <!-- 查询表单 --> <el-form :inline="true" class="search-form"> <el-form-item label="用户名"> <el-input v-model="queryParams.name" clearable @clear="handleQuery" /> </el-form-item> <el-form-item> <el-button type="primary" @click="handleQuery">查询</el-button> <el-button @click="resetQuery">重置</el-button> </el-form-item> </el-form> <!-- 操作按钮 --> <div class="operation-buttons"> <el-button type="primary" @click="handleAdd">新增</el-button> <el-button type="danger" @click="handleBatchDelete">批量删除</el-button> </div> <!-- 数据表格 --> <el-table v-loading="loading" :data="tableData" @selection-change="handleSelectionChange" > <el-table-column type="selection" width="55" /> <el-table-column prop="name" label="姓名" /> <el-table-column prop="age" label="年龄" /> <el-table-column label="操作" width="200"> <template #default="scope"> <el-button size="small" @click="handleEdit(scope.row)">编辑</el-button> <el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button> </template> </el-table-column> </el-table> <!-- 分页组件 --> <pagination v-show="total > 0" :total="total" v-model:page="queryParams.currentPage" v-model:limit="queryParams.pageSize" @pagination="handleQuery" /> <!-- 新增/编辑对话框 --> <el-dialog v-model="dialogVisible" :title="dialogTitle"> <el-form :model="form" :rules="rules" ref="formRef"> <el-form-item label="姓名" prop="name"> <el-input v-model="form.name" /> </el-form-item> <el-form-item label="年龄" prop="age"> <el-input-number v-model="form.age" :min="0" /> </el-form-item> </el-form> <template #footer> <el-button @click="dialogVisible = false">取消</el-button> <el-button type="primary" @click="submitForm">确定</el-button> </template> </el-dialog> </div> </template>
六、性能优化建议
后端优化:
使用MyBatis-Plus的分页插件替代手动分页
添加Redis缓存高频访问数据
对大数据量查询添加索引
前端优化:
使用防抖处理频繁查询
添加表格加载状态
实现数据懒加载
javascript
复制
下载
// 防抖处理示例 import { debounce } from 'lodash-es' const debouncedQuery = debounce(handleQuery, 500)
七、常见问题解决
跨域问题:确保后端正确配置CORS,前端请求地址正确
分页失效:检查分页参数是否正确传递,后端SQL是否正确拼接
数据更新不及时:在增删改操作后重新查询数据
批量操作失败:检查后端是否支持批量操作,参数格式是否正确
结语
本文详细介绍了基于Vue3和SpringBoot的全栈CRUD开发流程,涵盖了从基础查询到复杂分页的实现,以及前后端交互的最佳实践。读者可以根据实际需求扩展更多功能,如表单验证、文件上传、权限控制等。欢迎交流。