page.tsx
"use client"
IMPort AddTodo from "@/components/AddTodo";
import Todolist from "@/components/TodoList";
import TodoFilter from "@/components/TodoFilter";
import {useState} from "react";
import {Todo} from "@/types";
export default function Home() {
// todos 为事项对象的数组 { id: number, text:string, completed:boolean }
const [todos, setTodos] = useState([])
const [filter, setFilter] = useState('all')
const addTodo = (text: string) => {
const newTodo = {
id: Date.now(),
text,
completed: false
}
setTodos([...todos, newTodo])
}
const deleteTodo = (id:number) => {
setTodos(todos.filter(todo=> todo.id !== id))
}
const toggleTodo = (id: number) => {
setTodos(todos.map(todo=> {
if (todo.id === id) {
todo.completed = !todo.completed
}
return todo
}))
}
const getFilteredTodos = () => {
switch (filter) {
case 'completed':
return todos.filter(todo => todo.completed)
case 'active':
return todos.filter(todo => !todo.completed)
default:
return todos
}
}
return (
TodoList
)
}
AddTodo.tsx
import React, {useState} from "react";
interface AddTodoProps {
addTodo: (text: string) => void
}
function AddTodo({addTodo}: AddTodoProps) {
const [text, setText] = useState('')
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault()
if (text.trim() === '') {
return
}
addTodo(text)
setText('')
}
return (
setText(e.target.value)}/>
新建事项
)
}
export default AddTodo
TodoFilter.tsx
interface SetFilterProps {
setFilter: (text: string) => void
}
function TodoFilter ({ setFilter }: SetFilterProps){
return (
setFilter('all')}>全部
setFilter('active')}>待办
setFilter('completed')}>已办
)
}
export default TodoFilter
TodoItem.tsx
import {Todo} from "@/types";
interface TodoListProps {
todo: Todo
toggleTodo: (id: number) => void
deleteTodo: (id: number) => void
}
function TodoItem({todo, toggleTodo, deleteTodo}: TodoListProps) {
return (
{textDecoration: todo.completed ? 'line-through': 'none'}}
{todo.text}
toggleTodo(todo.id)}>切换
deleteTodo(todo.id)}>删除
)
}
export default TodoItem
TodoList.tsx
import {Todo} from "@/types";
import TodoItem from "@/components/TodoItem";
interface TodoListProps {
todos: Array
toggleTodo: (id: number) => void
deleteTodo: (id: number) => void
}
function TodoList({todos, toggleTodo, deleteTodo}: TodoListProps) {
return (
)
}
export default TodoList
types.ts
export interface Todo {
id: number
text: string
completed: boolean
}
