最普通的 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.js2. 后端实现(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=true2.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 install3.2 安装 Axios
安装 Axios 用于 HTTP 请求:
npm install axios3.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: 似水流年