初始版本
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user