最普通的 CRUDS 能10分钟快速搞定吗
Table of Contents
1. 项目结构
我们将项目分为两个部分:
- 后端:Spring Boot + Spring Data JPA + MySQL
- 前端:Vue.js 3
项目结构如下:
task-manager/
├── backend/ # Spring Boot 项目
│ ├── src/
│ │ ├── main/
│ │ │ ├── java/
│ │ │ │ └── com/
│ │ │ │ └── example/
│ │ │ │ ├── controller/
│ │ │ │ ├── model/
│ │ │ │ ├── repository/
│ │ │ │ └── service/
│ │ │ └── resources/
│ │ │ ├── application.properties
│ │ │ └── data.sql
│ │ └── test/
│ └── pom.xml
└── frontend/ # Vue.js 3 项目
├── public/
├── src/
│ ├── assets/
│ ├── components/
│ ├── router/
│ ├── views/
│ ├── App.vue
│ └── main.js
├── package.json
└── vite.config.js
2. 后端实现(Spring Boot + Spring Data JPA + MySQL)
2.1 配置 MySQL 数据库
在 application.properties
中配置 MySQL 连接:
spring.datasource.url=jdbc:mysql://localhost:3306/task_manager
spring.datasource.username=root
spring.datasource.password=yourpassword
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
2.2 创建 Task 实体类
在 model
包中创建 Task.java
:
package com.example.model;
import jakarta.persistence.*;
import java.time.LocalDateTime;
@Entity
public class Task {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String priority;
private int duration; // in minutes
private LocalDateTime scheduleTime;
private LocalDateTime startTime;
private LocalDateTime endTime;
private LocalDateTime deadline;
// Getters and Setters
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getPriority() { return priority; }
public void setPriority(String priority) { this.priority = priority; }
public int getDuration() { return duration; }
public void setDuration(int duration) { this.duration = duration; }
public LocalDateTime getScheduleTime() { return scheduleTime; }
public void setScheduleTime(LocalDateTime scheduleTime) { this.scheduleTime = scheduleTime; }
public LocalDateTime getStartTime() { return startTime; }
public void setStartTime(LocalDateTime startTime) { this.startTime = startTime; }
public LocalDateTime getEndTime() { return endTime; }
public void setEndTime(LocalDateTime endTime) { this.endTime = endTime; }
public LocalDateTime getDeadline() { return deadline; }
public void setDeadline(LocalDateTime deadline) { this.deadline = deadline; }
}
2.3 创建 TaskRepository 接口
在 repository
包中创建 TaskRepository.java
:
package com.example.repository;
import com.example.model.Task;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface TaskRepository extends JpaRepository<Task, Long> {
List<Task> findByNameContaining(String name); // 搜索功能
}
2.4 创建 TaskService 服务类
在 service
包中创建 TaskService.java
:
package com.example.service;
import com.example.model.Task;
import com.example.repository.TaskRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class TaskService {
@Autowired
private TaskRepository taskRepository;
public List<Task> getAllTasks() {
return taskRepository.findAll();
}
public Task getTaskById(Long id) {
return taskRepository.findById(id).orElse(null);
}
public Task createTask(Task task) {
return taskRepository.save(task);
}
public Task updateTask(Long id, Task taskDetails) {
Task task = taskRepository.findById(id).orElse(null);
if (task != null) {
task.setName(taskDetails.getName());
task.setPriority(taskDetails.getPriority());
task.setDuration(taskDetails.getDuration());
task.setScheduleTime(taskDetails.getScheduleTime());
task.setStartTime(taskDetails.getStartTime());
task.setEndTime(taskDetails.getEndTime());
task.setDeadline(taskDetails.getDeadline());
return taskRepository.save(task);
}
return null;
}
public void deleteTask(Long id) {
taskRepository.deleteById(id);
}
public List<Task> searchTasks(String name) {
return taskRepository.findByNameContaining(name);
}
}
2.5 创建 TaskController 控制器
在 controller
包中创建 TaskController.java
:
package com.example.controller;
import com.example.model.Task;
import com.example.service.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/tasks")
public class TaskController {
@Autowired
private TaskService taskService;
@GetMapping
public List<Task> getAllTasks() {
return taskService.getAllTasks();
}
@GetMapping("/{id}")
public Task getTaskById(@PathVariable Long id) {
return taskService.getTaskById(id);
}
@PostMapping
public Task createTask(@RequestBody Task task) {
return taskService.createTask(task);
}
@PutMapping("/{id}")
public Task updateTask(@PathVariable Long id, @RequestBody Task taskDetails) {
return taskService.updateTask(id, taskDetails);
}
@DeleteMapping("/{id}")
public void deleteTask(@PathVariable Long id) {
taskService.deleteTask(id);
}
@GetMapping("/search")
public List<Task> searchTasks(@RequestParam String name) {
return taskService.searchTasks(name);
}
}
3. 前端实现(Vue.js 3)
3.1 创建 Vue.js 项目
使用 Vite 创建 Vue.js 项目:
npm create vite@latest frontend --template vue
cd frontend
npm install
3.2 安装 Axios
安装 Axios 用于 HTTP 请求:
npm install axios
3.3 创建 Task 组件
在 src/components/
下创建 TaskList.vue
和 TaskForm.vue
。
TaskList.vue
<template>
<div>
<h1>Task List</h1>
<input v-model="searchQuery" placeholder="Search tasks" @input="searchTasks" />
<ul>
<li v-for="task in tasks" :key="task.id">
{{ task.name }} - {{ task.priority }}
<button @click="editTask(task)">Edit</button>
<button @click="deleteTask(task.id)">Delete</button>
</li>
</ul>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
tasks: [],
searchQuery: ''
};
},
created() {
this.fetchTasks();
},
methods: {
fetchTasks() {
axios.get('http://localhost:8080/api/tasks').then(response => {
this.tasks = response.data;
});
},
searchTasks() {
axios.get(`http://localhost:8080/api/tasks/search?name=${this.searchQuery}`).then(response => {
this.tasks = response.data;
});
},
editTask(task) {
this.$emit('edit-task', task);
},
deleteTask(id) {
axios.delete(`http://localhost:8080/api/tasks/${id}`).then(() => {
this.fetchTasks();
});
}
}
};
</script>
TaskForm.vue
<template>
<div>
<h2>{{ editMode ? 'Edit Task' : 'Create Task' }}</h2>
<form @submit.prevent="submitForm">
<input v-model="task.name" placeholder="Name" required />
<input v-model="task.priority" placeholder="Priority" required />
<input v-model="task.duration" type="number" placeholder="Duration (minutes)" required />
<input v-model="task.scheduleTime" type="datetime-local" placeholder="Schedule Time" />
<input v-model="task.startTime" type="datetime-local" placeholder="Start Time" />
<input v-model="task.endTime" type="datetime-local" placeholder="End Time" />
<input v-model="task.deadline" type="datetime-local" placeholder="Deadline" />
<button type="submit">{{ editMode ? 'Update' : 'Create' }}</button>
</form>
</div>
</template>
<script>
import axios from 'axios';
export default {
props: {
taskToEdit: {
type: Object,
default: () => ({})
}
},
data() {
return {
task: { ...this.taskToEdit },
editMode: !!this.taskToEdit.id
};
},
methods: {
submitForm() {
if (this.editMode) {
axios.put(`http://localhost:8080/api/tasks/${this.task.id}`, this.task).then(() => {
this.$emit('task-updated');
});
} else {
axios.post('http://localhost:8080/api/tasks', this.task).then(() => {
this.$emit('task-created');
});
}
}
}
};
</script>
3.4 在 App.vue 中使用组件
<template>
<div>
<TaskForm :taskToEdit="taskToEdit" @task-created="fetchTasks" @task-updated="fetchTasks" />
<TaskList @edit-task="setTaskToEdit" />
</div>
</template>
<script>
import TaskForm from './components/TaskForm.vue';
import TaskList from './components/TaskList.vue';
export default {
components: {
TaskForm,
TaskList
},
data() {
return {
taskToEdit: {}
};
},
methods: {
fetchTasks() {
this.$refs.taskList.fetchTasks();
},
setTaskToEdit(task) {
this.taskToEdit = task;
}
}
};
</script>
4. 运行项目
- 启动 Spring Boot 后端:
cd backend mvn spring-boot:run
- 启动 Vue.js 前端:
cd frontend npm run dev
- 访问
http://localhost:5173
即可使用 Task 管理功能。
通过以上步骤,我们快速实现了一个基于 Spring Boot + Vue.js 的 Task CRUDS 应用!
Comments |0|
Category: 似水流年