Vue3+typesctipt实现todolist效果
前言
大家好 我是歌谣 今天继续给大家带来一个V3+ts实现的todolist的项目
目录结构
主要代码
TodoInput----index.vue
<template> <div> <input type="text" v-model="todoValue" @keyup="setTodoValue"/> </div> </template> <script lang="ts"> import { defineComponent,reactive,ref } from 'vue'; import {IUseTodo, useTodo} from "../../hooks/index" export default defineComponent({ name:"TodoInput", setup(){ const todoValue=ref<string>("") const setTodoValue=(e:KeyboardEvent)=>{ console.log(todoValue.value) const {setTodo}:IUseTodo=useTodo() if(e.keyCode===13&&todoValue.value.trim().length){ setTodo(todoValue.value) todoValue.value='' } } return { todoValue, setTodoValue } } }) </script> <style> </style>
TodoList---index.vue
<template> <todo-item v-for="(item, index) of todoList" :key="item.id" :item="item" @removeTodo="removeTodo" @setStatus="setStatus" @setDoing="setDoing" /> <!-- --> </template> <script lang="ts"> import { defineComponent,PropType } from 'vue'; import TodoItem from "./item.vue" import { ITodo } from '@/typings'; import { useTodo } from '@/hooks'; export default defineComponent({ name: "TodoList", props:{ todoList:Array as PropType<ITodo[]> }, components: { TodoItem }, setup(props){ const {removeTodo,setStatus,setDoing}=useTodo() return{ removeTodo, setStatus, setDoing } } }) </script> <style></style>
TodoList---item.vue
<template> <div> <input type="checkbox" :checked="item?.status === FINISHED" @click="setStatus(item!.id)" /> <span :class="item?.status === FINISHED ? 'line-through' : ''">{{ item?.content }}</span> <button @click="removeTodo(item!.id)">删除</button> <button :class="item?.status === DOING ? 'doing' : 'willdo'" @click="setDoing(item!.id)" v-if="item?.status !== FINISHED">{{ item?.status === DOING ? "正在进行...." : "马上做...." }}</button> </div> </template> <script lang="ts"> import { ITodo, TODO_STATUS } from '@/typings'; import { PropType, defineComponent } from 'vue'; interface IStatusState { DOING: TODO_STATUS, FINISHED: TODO_STATUS, WILLDO: TODO_STATUS } export default defineComponent({ name: "TodoItem", props: { item: Object as PropType<ITodo> }, setup(props, { emit }) { const statusState: IStatusState = { DOING: TODO_STATUS.DOING, FINISHED: TODO_STATUS.FINISHED, WILLDO: TODO_STATUS.WILLDO } const removeTodo = (id: number): void => { console.log(111111,"id") emit("removeTodo", id) } const setDoing = (id: number): void => { emit("setDoing", id) } const setStatus = (id: number): void => { emit("setStatus", id) } return { ...statusState, removeTodo, setDoing, setStatus } } }) </script> <style> .line-through { text-decoration: line-through; } .doing { background-color: #ededed; color: #999; } .willdo { background-color: orange; color: #fff; } </style>
hooks---index.ts
import { SET_TODO, SET_TODO_LIST,REMOVE_TODO,SET_TODO_STATUS,SET_DOING_STATUS } from "@/store/actionTypes" import { ITodo, TODO_STATUS } from "@/typings" import { Store, useStore } from "vuex" import _store from "@/store" import { watch } from "vue" export interface IUseTodo { setTodo: (value: string) => void setTodoList: () => void removeTodo: (id:number) => void setStatus: (id:number) => void setDoing: (id:number) => void } interface IUseLocalStorage{ getLocalList:()=>ITodo[], setLocalList:(todoList:ITodo[])=>void } function useTodo(): IUseTodo { const store: Store<any> = useStore() || _store const {setLocalList,getLocalList}=useLocalStorage() const todolist:ITodo[]=getLocalList() watch(()=>{ return store.state.list },(todoList)=>{ setLocalList(todoList) }) function setTodo(value: string): void { const todo: ITodo = { id: new Date().getTime(), content: value, status: TODO_STATUS.WILLDO } store.dispatch(SET_TODO, todo) } function setTodoList() { store.dispatch(SET_TODO_LIST, todolist) } function removeTodo(id:number) { console.log("111111") store.dispatch(REMOVE_TODO, id) } function setStatus(id:number) { store.dispatch(SET_TODO_STATUS, id) } function setDoing(id:number) { store.dispatch(SET_DOING_STATUS, id) } return { setTodo, setTodoList, removeTodo, setStatus, setDoing } } function useLocalStorage():IUseLocalStorage { function getLocalList(): ITodo[] { return JSON.parse(localStorage.getItem("todoList") || '[]') } function setLocalList(todoList: ITodo[]): void { localStorage.setItem("todoList",JSON.stringify(todoList)) } return { getLocalList, setLocalList } } export { useTodo }
app.vue
<template> <div class="warpper"> <todo-input></todo-input> <todo-list :todo-list="todoList"></todo-list> </div> </template> <script lang="ts"> import { computed, defineComponent, onMounted } from 'vue'; import TodoInput from './components/TodoInput/index.vue'; import TodoList from './components/TodoList/index.vue'; import { IUseTodo, useTodo } from './hooks'; import { Store, useStore } from 'vuex'; export default defineComponent({ name: 'App', components: { TodoInput, TodoList }, setup(){ const {setTodoList}:IUseTodo=useTodo() const store:Store<any>=useStore() onMounted(()=>{ setTodoList() }) return { todoList:computed(()=>store.state.list) } } }); </script> <style> </style>
运行结果
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南