Vue3+typesctipt实现todolist效果

 前言

20b4fae6757a83ed855a368252533d4e.png

 大家好 我是歌谣 今天继续给大家带来一个V3+ts实现的todolist的项目

  目录结构

9618601348bcfb8759f23a7b208681c4.png

93e65320619038b8207c94d03b82f0b3.png

 主要代码

0a91051aad82179a9281090669357b04.png

  TodoInput----index.vue

9c76aa3210649ab5d888686260b77956.png

<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

e481e2f2f7a18842b0e4d9b4f2130443.png

<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

604a5413f574f7c14a21657f488f46b5.png

<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

e7b829a409f15ea49ba14302e9154da4.png

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

13cc0a046b45355dc5eaa01bab913778.png

<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>

 运行结果

a1e3b8f197c1dea2d29778deb728ec6f.png

4056f914a281070abeb802886153cfba.png

f82992d99845c9e2df65d420015044c7.png

5007023c11582f6dbe38595bb306719b.png

posted @   前端导师歌谣  阅读(77)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示