初始版本

This commit is contained in:
z66
2025-12-26 13:42:22 +08:00
parent ddb90d6c20
commit b495bc1dca
43 changed files with 2179 additions and 20 deletions
+148
View File
@@ -0,0 +1,148 @@
<template>
<div class="todos">
<h1>待办事项</h1>
<div v-if="!isAuthenticated" class="warning">
请先 <router-link to="/login">登录</router-link>
</div>
<div v-else>
<form @submit.prevent="addTodo">
<input v-model="newTodo" placeholder="输入待办事项..." />
<button type="submit">添加</button>
</form>
<ul>
<li v-for="todo in todos" :key="todo.id">
<input
type="checkbox"
:checked="todo.done"
@change="toggleTodo(todo)"
/>
<span :class="{ done: todo.done }">{{ todo.title }}</span>
<button @click="deleteTodo(todo.id)">删除</button>
</li>
</ul>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, computed } from 'vue'
import axios from 'axios'
import { useAuthStore } from '../stores/auth'
const authStore = useAuthStore()
const isAuthenticated = computed(() => authStore.isAuthenticated)
const todos = ref([])
const newTodo = ref('')
const fetchTodos = async () => {
try {
const response = await axios.get('/api/v1/todos/')
todos.value = response.data
} catch (error) {
console.error('获取待办事项失败:', error)
}
}
const addTodo = async () => {
if (!newTodo.value.trim()) return
try {
const response = await axios.post('/api/v1/todos/', {
title: newTodo.value
})
todos.value.push(response.data)
newTodo.value = ''
} catch (error) {
console.error('添加待办事项失败:', error)
}
}
const toggleTodo = async (todo) => {
try {
const response = await axios.put(`/api/v1/todos/${todo.id}`, {
done: !todo.done
})
const index = todos.value.findIndex(t => t.id === todo.id)
todos.value[index] = response.data
} catch (error) {
console.error('更新待办事项失败:', error)
}
}
const deleteTodo = async (id) => {
try {
await axios.delete(`/api/v1/todos/${id}`)
todos.value = todos.value.filter(t => t.id !== id)
} catch (error) {
console.error('删除待办事项失败:', error)
}
}
onMounted(() => {
if (isAuthenticated.value) {
fetchTodos()
}
})
</script>
<style scoped>
.todos {
max-width: 600px;
margin: 0 auto;
}
.warning {
padding: 20px;
background: #fff3cd;
border: 1px solid #ffc107;
border-radius: 5px;
margin-bottom: 20px;
}
.todos form {
margin-bottom: 20px;
display: flex;
gap: 10px;
}
.todos input[type="text"] {
flex: 1;
padding: 8px;
}
.todos button {
padding: 8px 15px;
background: #42b983;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
.todos ul {
list-style: none;
padding: 0;
}
.todos li {
display: flex;
align-items: center;
gap: 10px;
padding: 10px;
margin: 5px 0;
background: #f5f5f5;
border-radius: 5px;
}
.todos li span.done {
text-decoration: line-through;
color: #999;
}
.todos li button {
margin-left: auto;
background: #dc3545;
padding: 5px 10px;
}
</style>