前言

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

目录结构

前端歌谣-第十一课-Vue3+typesctipt实现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>

运行结果

前端歌谣-第十一课-Vue3+typesctipt实现todolist效果_App_02

前端歌谣-第十一课-Vue3+typesctipt实现todolist效果_App_03

前端歌谣-第十一课-Vue3+typesctipt实现todolist效果_App_04