Todo-app开发流程
一、后端配置
1.1创建Springboot工程
打开idea->file->new->project
选择spring Initializer进行配置,java版本选择8,点击next
Springboot版本选3.0以下版本,勾选Lombok和spring Web这两个依赖一会都会用到
进入目录src.java.com.zjz._01todo下可以看到已经创建好了启动类Application,点击绿色三角启动Springboot应用
可以看到在8080端口已经启动服务
创建一个controller包,编写测试类HelloController
注意:该类上需要加注解@RestController
@RestController
public class HelloController {
@RequestMapping("/hello")
public String Hello(){
return "Hello";
}
}
打开浏览输入http://localhost:8080/hello就可以看到页面输出Hello,该工程就没有问题
1.2.数据库表创建
CREATE TABLE tasks (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
completed BOOLEAN
);
INSERT INTO mybatis_db.tasks (id, name, completed)
VALUES (1, '吃饭', 0);
我直接使用idea连接本地mysql在数据库mybatis_db中创建tasks表,含有三个字段
1.3实体类创建
创建实体类Task,在com.zjz._01todo下创建domain包,创建实体类Task,实体类中字段名称和数据类型严格对照tasks表。
上面三个注解是Lombok提供用来自动添加构造函数和set,get方法,很方便
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Task {
private Long id;
private String name;
private Boolean completed;
}
1.4获取所有任务方法实现
1.4.1编写controller层业务
在controller包下创建TaskController
@RestController
public class TaskController {
@Autowired
private TaskService taskService;
@GetMapping("/tasks")
public List<Task> getAllTask(){
return taskService.getAllTask();
}
}
我们要求改方法返回所有任务,所有返回类型用List封装,同时注入TaskService,调用个getAllTask方法来实现。
1.4.2编写Service层
首先创建service包,包下创建接口TaskService
public interface TaskService {
List<Task> getAllTask();
}
1.4.3下面在service包下创建impl包用于写实现类
impl下创建TaskService的实现类TaskServiceImpl类
注意:添加注解@Service,重新方法getAllTask() ,注入mapper层taskMapper,调用mapper层方法对数据库进行操作
@Service
public class TaskServiceImpl implements TaskService {
@Autowired
private TaskMapper taskMapper;
@Override
public List<Task> getAllTask() {
return taskMapper.getAllTask();
}
}
1.4.4添加数据库操作所需依赖
在pom.xml文件中添加以下依赖
<!--mybatis启动器-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
<scope>runtime</scope>
</dependency>
1.4.5配置application.yml文件
在resource目录下添加文件application.yml文件
还有mybatis的配置
server:
port: 8080
#整合Mybatis相关配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/mybatis_db?characterEncoding=utf-8&serverTimezone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath:mapper/*Mapper.xml #mapper映射文件路径
type-aliases-package: com.zjz._01todo.domain #配置哪个包下面的类有默认的别名
1.4.6创建mapper接口
创建mapper包,taskMapper接口
@Mapper
public interface TaskMapper {
List<Task> getAllTask();
}
1.4.7编写mapper.xml文件,进行数据库操作
在resource包下创建mapper文件夹,创建TaskMapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.zjz._01todo.mapper.TaskMapper">
<select id="getAllTask" resultType="com.zjz._01todo.domain.Task">
select * from tasks
</select>
</mapper>
至此,该功能的后端编码已经完成,测试一下,启动应用,打开浏览器输入http://localhost:8080/tasks
看到这个说明成功了
1.4.8统一返回对象
在domain包下创建CommonResult类
import lombok.Data;
import java.io.Serializable;
@Data
public class CommonResult<T> implements Serializable {
private Integer code;
private String msg;
private T data;
public static <T> CommonResult<T> success(T data) {
CommonResult<T> result = new CommonResult<>();
result.code = 200;
result.data = data;
result.msg = "操作成功";
return result;
}
public static <T> CommonResult<T> error(Integer code, String message) {
CommonResult<T> result = new CommonResult<>();
result.code = code;
result.msg = message;
return result;
}
}
修改controller方法
@RestController
public class TaskController {
@Autowired
private TaskService taskService;
@GetMapping("/tasks")
public CommonResult<?> getAllTask(){
return CommonResult.success(taskService.getAllTask());
}
}
重启应用,打开浏览器输入http://localhost:8080/tasks
成功!
1.5 剩余方法实现
1.5.1 controller层
@RestController
public class TaskController {
@Autowired
private TaskService taskService;
@GetMapping("/tasks")
public CommonResult<?> getAllTask(){
return CommonResult.success(taskService.getAllTask());
}
//添加任务
@PostMapping("/tasks")
public CommonResult<?> addTask(@RequestBody Task task) {
return CommonResult.success(taskService.addTask(task));
}
//更新任务内容
@PutMapping("/tasks/{id}")
public CommonResult<?> updateTask(@PathVariable long id, @RequestBody Task task) {
task.setId(id);
return CommonResult.success(taskService.updateTask(task));
}
//删除任务
@DeleteMapping("/tasks/{id}")
public CommonResult<?> deleteTask(@PathVariable long id) {
return CommonResult.success(taskService.deleteTask(id));
}
}
1.5.2 Service层
public interface TaskService {
List<Task> getAllTask();
int addTask(Task task);
int updateTask(Task task);
int deleteTask(long id);
}
1.5.3 Service实现类
@Service
public class TaskServiceImpl implements TaskService {
@Autowired
private TaskMapper taskMapper;
@Override
public List<Task> getAllTask() {
return taskMapper.getAllTask();
}
@Override
public int addTask(Task task) {
return taskMapper.addTask(task);
}
@Override
public int updateTask(Task task) {
return taskMapper.updateTask(task);
}
@Override
public int deleteTask(long id) {
return taskMapper.deleteTask(id);
}
}
1.5.4 Mapper接口类
@Mapper
public interface TaskMapper {
List<Task> getAllTask();
int addTask(Task task);
int updateTask(Task task);
int deleteTask(long id);
}
1.5.5 TaskMapper.xml编写
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.zjz._01todo.mapper.TaskMapper">
<insert id="addTask" parameterType="com.zjz._01todo.domain.Task">
INSERT INTO tasks(name,completed) VALUES (#{name},#{completed})
</insert>
<update id="updateTask" parameterType="com.zjz._01todo.domain.Task">
UPDATE tasks SET name=#{name},completed=#{completed} WHERE id=#{id}
</update>
<delete id="deleteTask">
DELETE FROM tasks WHERE id=#{id}
</delete>
<select id="getAllTask" resultType="com.zjz._01todo.domain.Task">
select * from tasks
</select>
</mapper>
1.6 接口测试
使用软件Apifox对编写的三个接口进行测试
添加任务测试
查询所有任务,可以看到已添加,id数据库会自动添加
测试更新任务
测试删除任务
所有接口测试成功
1.7 补充跨域配置
创建config包,编写如下文件
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*") // 使用allowedOriginPatterns替代allowedOrigins
.allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")
.allowedHeaders("Authorization", "Cache-Control", "Content-Type")
.allowCredentials(true)
.maxAge(3600);
}
}
二、前端配置
2.1 Vue工程创建
至于VUE的安装啥的就不写了
找到要存放工程的文件夹,在文件管理器上输入cmd打开命令控制器
输入以下命令创建vue工程
vue create todovue
开始创建,等一会
创建完成后有VsCode打开
终端运行 npm run serve ,单击生成的链接
2.2前端项目编写
编写App.vue文件
<template>
<div id="app">
<div>
<input type="text" v-model="newTask" placeholder="请输入你的任务名称">
<button @click="addTask">添加</button>
</div>
<div>
<ul>
<li v-for="task in tasks" :key="task.id" :class="{ completed: task.completed }">
<span @click="toggleCompletion(task)">{{ task.name }}</span>
<button @click="deleteTask(task)">删除</button>
</li>
</ul>
</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: 'App',
data() {
return {
newTask: '',
tasks: [],
};
},
created() {
this.fetchTasks();
},
methods: {
addTask() {
if (this.newTask.trim()) {
this.tasks.push({ id: Date.now(), name: this.newTask.trim(), completed: false });
this.newTask = '';
}
},
fetchTasks() {
axios.get('http://localhost:8080/tasks')
.then(response => {
if (response.data.code === 200) {
this.tasks = response.data.data;
} else {
console.error(response.data.msg);
}
})
.catch(error => {
console.error(error);
});
},
deleteTask(task) {
axios.delete(`http://localhost:8080/tasks/${task.id}`)
.then(response => {
if (response.data.code === 200) {
this.fetchTasks(); // 重新获取任务列表
} else {
console.error(response.data.msg);
}
})
.catch(error => {
console.error(error);
});
},
addTask() {
if (this.newTask.trim()) {
const task = { name: this.newTask.trim(), completed: false };
axios.post('http://localhost:8080/tasks', task)
.then(response => {
if (response.data.code === 200) {
this.newTask = '';
this.fetchTasks(); // 重新获取任务列表
} else {
console.error(response.data.msg);
}
})
.catch(error => {
console.error(error);
});
}
},
toggleCompletion(task) {
task.completed = !task.completed;
axios.put(`http://localhost:8080/tasks/${task.id}`, task)
.then(response => {
if (response.data.code !== 200) {
console.error(response.data.msg);
}
})
.catch(error => {
console.error(error);
});
}
},
};
</script>
<style>
body {
font-family: 'Arial', sans-serif;
background-color: #F7F9FC;
padding: 20px;
}
li {
color: #333;
cursor: pointer;
padding: 5px;
border-radius: 3px;
transition: background-color 0.3s ease;
}
li:hover {
background-color: #E4E7ED;
}
.completed {
color: #A5ACB3;
text-decoration: line-through;
}
input[type="text"],
button {
padding: 10px;
border: 1px solid #D4D9E1;
border-radius: 4px;
font-size: 16px;
margin-right: 10px;
}
button {
background-color: #4C8EF7;
color: #FFF;
cursor: pointer;
transition: background-color 0.3s ease;
}
button:hover {
background-color: #357ABD;
}
</style>
注意:如果有报错 ERROR in [eslint],编辑vue.config.js文件,添加如下代码:
lintOnSave: false
2.3前后端调试
启动Springboot项目,然后在VsCode中断输入 npm run serve,单击链接即可