
前言
在现代化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开发流程,涵盖了从基础查询到复杂分页的实现,以及前后端交互的最佳实践。读者可以根据实际需求扩展更多功能,如表单验证、文件上传、权限控制等。欢迎交流。