vue3.0+vuex+typescript 入门项目描述

先写仓库地址:https://gitee.com/orderkk/vuex-vue3.0-ts.git

项目目录介绍:

在这里插入图片描述

目录介绍:

assets: 存放静态文件资源
components: 存放组件文件
hooks: 剥离了项目中的methods, 封装了一些基本方法
store:vuex存放的目录
typings: 存放typescript interface的目录

粘贴部分代码:

// @/store/index.ts
import { createStore } from 'vuex'
import state from './state'
import mutations from './mutations'
import actions from './actions'
export default createStore({
  state,
  mutations,
  actions,
  modules: {
  }
})
// @/store/actions.ts
import { IState, ITodo } from "@/typings";
import { Commit } from "vuex";
import { REMOVE_TODO, SET_DOING, SET_STATUS, SET_TODO, SET_TODO_LIST } from "./actionTypes";
interface ICtx {
    commit: Commit,
    state: IState
}
export default {
    [SET_TODO]({ commit }: ICtx, todo: ITodo): void {
        commit(SET_TODO, todo)
    },
    [SET_TODO_LIST]({ commit }: ICtx, todoList: ITodo[]): void {
        commit(SET_TODO_LIST, todoList)
    },
    [REMOVE_TODO]({ commit }: ICtx, id: number): void {
        commit(REMOVE_TODO, id)
    },
    [SET_STATUS]({ commit }: ICtx, id: number): void {
        commit(SET_STATUS, id)
    },
    [SET_DOING]({ commit }: ICtx, id: number): void {
        commit(SET_DOING, id)
    }
}Ï
// @/store/actionTypes.ts
export const SET_TODO: string = 'SET_TODO'
export const SET_TODO_LIST: string = 'SET_TODO_LIST'
export const REMOVE_TODO: string = 'REMOVE_TODO'
export const SET_STATUS: string = 'SET_STATUS'
export const SET_DOING: string = 'SET_DOING'
// @/store/mutations.ts
import { IState, ITodo, TODO_STATUS } from "@/typings";
import { REMOVE_TODO, SET_DOING, SET_STATUS, SET_TODO, SET_TODO_LIST } from "./actionTypes";

export default {
    [SET_TODO](state: IState, todo: ITodo): void {
        state.list = [todo, ...state.list]
    },
    [SET_TODO_LIST](state: IState, todoList: ITodo[]): void {
        state.list = todoList
    },
    [REMOVE_TODO](state: IState, id: number) {
        state.list = state.list.filter((item: ITodo) => item.id != id)
    },
    [SET_STATUS](state: IState, id: number) {
        state.list = state.list.map((item: ITodo) => {
            if (item.id === id) {
                switch (item.status) {
                    case TODO_STATUS.FINISHED:
                        item.status = TODO_STATUS.WILLDO
                        break;
                    case TODO_STATUS.WILLDO:
                        item.status = TODO_STATUS.FINISHED
                        break;
                    case TODO_STATUS.DOING:
                        item.status = TODO_STATUS.FINISHED
                        break;
                    default:
                        break;
                }
            }
            return item
        })
    },
    [SET_DOING](state: IState, id: number) {
        state.list = state.list.map((item: ITodo) => {
            if (item.id != id) {
                if (item.status === TODO_STATUS.DOING) {
                    item.status = TODO_STATUS.WILLDO
                }
            } else {
                item.status = item.status === TODO_STATUS.WILLDO ? TODO_STATUS.DOING : TODO_STATUS.WILLDO
            }
            return item
        })
    }
}
// @/store/state.ts
import { IState } from "@/typings";
export default <IState>{
    list: []
}
// @/typings/index.ts
enum TODO_STATUS {
    FINISHED = 'finished',
    WILLDO = 'willdo',
    DOING = 'doing'
}
interface ITodo {
    id: number,
    content: string,
    status: TODO_STATUS
}
interface IState {
    list: ITodo[]
}
export {
    TODO_STATUS,
    ITodo,
    IState
}
// @/App.vue
<template>
  <div class="wrapper">
    <todo-input />
    <todo-list :todoLists="todoLists" />
  </div>
</template>
<script lang="ts">
import { computed, defineComponent, onMounted } from "vue";
import TodoList from "./components/TodoList/Index.vue";
import TodoInput from "./components/TodoInput/Index.vue";
import { IUseTodo, useTodo } from "./hooks";
import { Store, useStore } from "vuex";
export default defineComponent({
  name: "App",
  components: {
    TodoList,
    TodoInput,
  },
  setup() {
    const { setTodoList }: IUseTodo = useTodo();
    const store: Store<any> = useStore();
    onMounted(() => {
      setTodoList();
    });
    return {
      todoLists: computed(() => {
        return store.state.list;
      }),
    };
  },
});
</script>
// @/hooks/index.ts
import { REMOVE_TODO, SET_DOING, SET_STATUS, SET_TODO, SET_TODO_LIST } from "@/store/actionTypes"
import { ITodo, TODO_STATUS } from "@/typings"
import { watch } from "vue"
import { Store, useStore } from "vuex"
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 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
    }
}
function useTodo(): IUseTodo {
    const store: Store<any> = useStore();
    const { getLocalList, setLocalList }: IUseLocalStorage = useLocalStorage();
    const todolist: ITodo[] = getLocalList()
    watch(() => {
        return store.state.list
    }, (todolist) => {
        setLocalList(todolist)
    })
    function setTodo(value: string): void {
        const todo: ITodo = {
            id: Date.now(),
            content: value,
            status: TODO_STATUS.WILLDO
        }

        store.dispatch(SET_TODO, todo)
        // setLocalList(store.state.list)
    }
    function setTodoList(): void {
        store.dispatch(SET_TODO_LIST, todolist)
    }
    function removeTodo(id: number): void {
        store.dispatch(REMOVE_TODO, id)
        // setLocalList(store.state.list)
    }
    function setStatus(id: number): void {
        store.dispatch(SET_STATUS, id)
        // setLocalList(store.state.list)
    }
    function setDoing(id: number): void {
        store.dispatch(SET_DOING, id)
        // setLocalList(store.state.list)
    }
    return {
        setTodo,
        setTodoList,
        removeTodo,
        setStatus,
        setDoing
    }
}
export {
    IUseTodo,
    useTodo,
    useLocalStorage
}
// @/components/TodoInput/Index.vue
<template>
  <div>
    <input type="text" v-model="todoValue" @keyup.enter="setTodoValue" />
  </div>
</template>
<script lang="ts">
import { defineComponent, reactive, ref } from "vue";
import { useTodo, IUseTodo } from "../../hooks/index";
export default defineComponent({
  name: "TodoInput",
  setup() {
    let todoValue = ref<string>("");
    const { setTodo }: IUseTodo = useTodo();
    const setTodoValue = (e: KeyboardEvent): void => {
      setTodo(todoValue.value);
      todoValue.value = "";
    };
    return {
      todoValue,
      setTodoValue,
    };
  },
});
</script>
// @/components/TodoList/Index.vue
<template>
  <div>
    <h1>todo-list</h1>
    <todo-item
      v-for="item in todoLists"
      :key="item.key"
      :item="item"
      @removeTodo="removeTodo"
      @setStatus="setStatus"
      @setDoing="setDoing"
    />
  </div>
</template>
<script lang="ts">
import { defineComponent, onMounted, PropType } from "vue";
import TodoItem from "./Item.vue";
import { ITodo } from "../../typings/index";
import { IUseTodo, useTodo } from "../../hooks";
export default defineComponent({
  name: "TodoList",
  props: {
    todoLists: Array as PropType<ITodo[]>,
  },
  components: {
    TodoItem,
  },
  setup(props, { emit }) {
    const { removeTodo, setStatus, setDoing }: IUseTodo = useTodo();
    return {
      removeTodo,
      setStatus,
      setDoing,
    };
  },
});
</script>
// @/components/TodoList/Item.vue
<template>
  <div>
    <input
      type="checkbox"
      :checked="item.status === FINISHED"
      @click="setStatus(item.id)"
    />
    <span :class="item.status === FINISHED ? 'line-thoungth' : ''">
      {{ item.content }}
    </span>
    <button @click="removeTodo(item.id)">删除</button>
    <button
      v-if="item.status != FINISHED"
      @click="setDoing(item.id)"
      :class="item.status === DOING ? 'doing' : 'willdo'"
    >
      {{ item.status === DOING ? "正在做..." : "马上做..." }}
    </button>
  </div>
</template>
<script lang="ts">
import { defineComponent, PropType } from "vue";
import { ITodo, TODO_STATUS } from "../../typings";
interface IStatusState {
  DOING: TODO_STATUS;
  WILLDO: TODO_STATUS;
  FINISHED: TODO_STATUS;
}
export default defineComponent({
  name: "TodoItem",
  props: {
    item: Object as PropType<ITodo>,
  },
  setup(props, { emit }) {
    const statusState: IStatusState = {
      DOING: TODO_STATUS.DOING,
      WILLDO: TODO_STATUS.WILLDO,
      FINISHED: TODO_STATUS.FINISHED,
    };
    const removeTodo = (id: number): void => {
      emit("removeTodo", id);
    };
    const setStatus = (id: number): void => {
      emit("setStatus", id);
    };
    const setDoing = (id: number): void => {
      emit("setDoing", id);
    };
    return {
      ...statusState,
      removeTodo,
      setStatus,
      setDoing,
    };
  },
});
</script>
<style scoped>
.line-thoungth {
  text-decoration: line-through;
}
.doing {
  background-color: #cdcdcd;
  color: red;
}
.willdo {
  background-color: orange;
  color: #fff;
}
</style>
// @/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import store from './store'

createApp(App).use(store).mount('#app')

好的目录结构可以让开发事半功倍,如果没有很好的见解或者是刚开始开发的朋友们,可以参考这个进行开发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值