前后端分离实战2----前端
对应后端链接戳我抵达后端解析
项目描述:用Vscode创建Spring Boot+mybatis项目,用maven进行管理。创建一个User表,对其内容进行表的基本操作(增删改查),显示在前端。前端使用vue框架进行显示。
项目地址:戳我一键下载项目
1.项目目录:
2.关键代码
1.与后端链接部分
一般有关数据库表的操作,都用axios来进行管理连接后端,获取数据。配置连接步骤:首先,在vite.config.js里面补充配置相关后端代理。接着,在src目录下新建api文件夹。在里面编写连接数据库表的js文件。最后再编写 相关的显示界面。
1)vite.config.js
import { fileURLToPath, URL } from 'node:url'import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'// https://vite.dev/config/
export default defineConfig({plugins: [vue(),vueDevTools(),],resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url))},},server: {proxy: {'/user': {target: 'http://localhost:8080',changeOrigin: true,}}}
})
解析:
server: {proxy: {'/user': {target: 'http://localhost:8080',changeOrigin: true,}}}
这里的'/user'是匹配所有以
/user
开头的API请求,这类请求将被转发到目标服务器。target指定后端服务器的实际地址,本例为本地8080端口服务。changeOrigin设置为true时,会修改请求头中的Host字段为目标服务器地址,避免某些服务器校验Origin。一般基本操作配置一下请求的前缀,后端服务器地址,还有changeOrigin:true,就可以了。
2)user.js
import axios from 'axios';const api = axios.create({baseURL: 'http://localhost:8080/user', // 你的后端地址timeout: 5000
});export default {// 获取用户列表getUsers() {return api.get('/list');},// 添加用户addUser(userData) {return api.post('/add', null, {params: {name: userData.name,email: userData.email}});},// 更新用户updateUser(userData) {return api.post('/update', null, {params: {id: userData.id,name: userData.name,email: userData.email}});},// 删除用户deleteUser(id) {return api.post('/delete', null, {params: { id }});}
}
解析:
axios.create
用于创建一个自定义的 axios 实例,以便连接后端数据。通过api.get方法来获取后端的操作接口。这些方法(getUsers()
、addUser()
、updateUser()
、deleteUser()
)是前端代码中定义的函数,用于与后端API进行交互。它们通过HTTP请求(GET/POST)调用后端提供的接口。
getUsers()
调用/list
接口获取用户列表。
addUser()
调用/add
接口提交用户数据。updateUser()调用 /update接口提交更新数据。
deletUser()调用 /delete接口删除指定对象。
api.post 用于发送 HTTP POST 请求,通常用于向服务器提交数据。POST 请求将数据放在请求体中,适合用于创建或修改操作。
api.get 用于发送 HTTP GET 请求,通常用于从服务器获取数据。GET 请求将参数附加在 URL 中,适合用于查询或读取操作。
2.前端展示部分
1.UserForm.vue
<template><form @submit.prevent="handleSubmit"><div class="form-group"><label>用户名:</label><input v-model="formData.name" required></div><div class="form-group"><label>邮箱:</label><input v-model="formData.email" type="email" required></div><div class="form-actions"><button type="submit">保存</button><button type="button" @click="$emit('cancel')">取消</button></div></form>
</template><script>
export default {props: {user: {type: Object,required: true}},data() {return {formData: { ...this.user }};},methods: {handleSubmit() {this.$emit('save', this.formData);}}
};
</script><style scoped>
.form-group {margin-bottom: 15px;
}.form-group label {display: block;margin-bottom: 5px;
}.form-group input {width: 100%;padding: 8px;box-sizing: border-box;
}.form-actions {margin-top: 20px;text-align: right;
}.form-actions button {margin-left: 10px;
}
</style>
解析:
这是子组件,定义propers属性,从父组件UserList.vue接收数据。这个表单就是编辑和新增用户时弹出来的表单。
props: { user }
的作用是让父组件(UserList.vue)把当前要操作的用户对象传递给表单组件(UserForm.vue)。表单的“增加”和“编辑”其实就是看传进来的user
是不是已有用户。具体流程如下:
- 增加用户时
父组件调用showAddForm()
,传递的是一个没有 id 的新对象:showAddForm() {this.currentUser = { name: '', email: '' };this.formTitle = '添加用户';this.showForm = true;}
此时
UserForm
里formData
就是空的,表单显示为空白,用户填写后点保存就是“新增”。2.编辑用户时
父组件调用editUser(user)
,传递的是已有用户对象(带 id)editUser(user) {this.currentUser = { ...user };this.formTitle = '编辑用户';this.showForm = true; }
此时
UserForm
里formData
就有原有数据,表单显示已有内容,用户修改后点保存就是“编辑”。3.保存时的判断
父组件的handleSave(userData)
方法会判断userData
是否有 id:handleSave(userData) {const action = userData.id ? userApi.updateUser(userData) // 有id,编辑: userApi.addUser(userData); // 没id,新增// ... }
- 传给
UserForm
的user
是否有 id,决定了表单是“新增”还是“编辑”。- 表单内容由
user
决定,保存时由父组件判断是新增还是编辑。
2.UserList.vue
<template><div class="user-management"><h2>用户管理系统</h2><button @click="showAddForm">添加用户</button><table class="user-table"><thead><tr><th>ID</th><th>用户名</th><th>邮箱</th><th>操作</th></tr></thead><tbody><tr v-for="user in users" :key="user.id"><td>{{ user.id }}</td><td>{{ user.name }}</td><td>{{ user.email }}</td><td><button @click="editUser(user)">编辑</button><button @click="deleteUser(user.id)">删除</button></td></tr></tbody></table><!-- 用户表单对话框 --><div v-if="showForm" class="form-modal"><div class="form-content"><h3>{{ formTitle }}</h3><UserForm :user="currentUser"@save="handleSave"@cancel="closeForm"/></div></div></div>
</template><script>
import UserForm from './UserForm.vue';
import userApi from '../api/user';export default {components: { UserForm },data() {return {users: [],showForm: false,currentUser: null,formTitle: '添加用户'};},created() {this.fetchUsers();},methods: {fetchUsers() {userApi.getUsers().then(response => {this.users = response.data;}).catch(error => {console.error('获取用户列表失败:', error);alert('获取用户列表失败,请检查控制台');});},showAddForm() {this.currentUser = { name: '', email: '' };this.formTitle = '添加用户';this.showForm = true;},editUser(user) {this.currentUser = { ...user };this.formTitle = '编辑用户';this.showForm = true;},deleteUser(id) {if (confirm('确定要删除这个用户吗?')) {userApi.deleteUser(id).then(() => {this.fetchUsers();alert('删除成功');}).catch(error => {console.error('删除失败:', error);alert('删除用户失败');});}},handleSave(userData) {const action = userData.id ? userApi.updateUser(userData): userApi.addUser(userData);action.then(() => {this.fetchUsers();this.closeForm();alert('操作成功');}).catch(error => {console.error('操作失败:', error);alert('操作失败,请检查控制台');});},closeForm() {this.showForm = false;}}
};
</script><style scoped>
.user-management {padding: 20px;max-width: 800px;margin: 0 auto;
}.user-table {width: 100%;border-collapse: collapse;margin-top: 20px;
}.user-table th, .user-table td {border: 1px solid #ddd;padding: 8px;text-align: left;
}.user-table th {background-color: #f2f2f2;
}button {margin: 0 5px;padding: 5px 10px;cursor: pointer;
}.form-modal {position: fixed;top: 0;left: 0;right: 0;bottom: 0;background-color: rgba(0,0,0,0.5);display: flex;justify-content: center;align-items: center;
}.form-content {background: white;padding: 20px;border-radius: 5px;width: 400px;
}
</style>
解析:
这是父组件,子组件是userForm.vue和user.js。
fetchUsers()
是在methods
里自定义的方法,用于从后端 API 获取用户列表数据,并赋值给组件的users
数组。这样页面上的用户表格就能显示所有用户信息。userApi.getUsers()
是封装的 API 请求方法,返回一个 Promise。请求成功后,把返回的数据赋值给this.users
,驱动表格渲染。如果请求失败,会在控制台输出错误,并弹窗提示用户。userApi.getUsers() 的userApi是axios的api对象,调用api.getUsers方法。具体是通过import userApi from '../api/user';来导入创建user.js里的api对象的。
扩展:
1.axios是什么
axios是一个基于Promise的HTTP客户端,专门用于浏览器和Node.js环境。简单来说,就是一个工具,用来发送网络请求(比如获取数据、提交表单等),比原生JavaScript的fetch
或XMLHttpRequest
更简单好用。
axios实例的作用
axios实例是通过axios.create()
创建的独立配置对象,作用如下:
1. 统一配置请求
比如设置统一的请求地址(baseURL
)、请求头(headers
)、超时时间等,避免每次请求重复写配置。
2. 隔离不同环境的请求
例如一个项目需要对接两个后端API,通过创建两个实例,分别配置不同的baseURL
,互不干扰。
3. 复用和模块化
将实例封装成模块,其他文件直接导入使用,避免代码重复。
总结:axios实例就像预装了固定设置的“定制版请求工具”,用起来更省事。
2. ...user是什么
在上面的代码中,...user
是 JavaScript 的对象展开运算符(spread operator),用于浅拷贝对象的属性。
具体用法如下:
this.currentUser = { ...user };
这行代码的作用是:
将 user
对象的所有属性(如 id、name、email)“展开”到一个新对象里,然后赋值给 currentUser
。
这样做的好处是,currentUser
和原来的 user
是两个独立的对象,后续在表单里修改 currentUser
不会影响原始的 user
数据。
简单理解:
{ ...user }
会生成一个和user
内容一样的新对象。- 这样可以避免直接修改原始数据,保证数据安全。
在你的场景下,editUser(user)
方法里用 { ...user }
,就是为了让表单编辑时的数据和表格里的原始数据分离。