记录:vue3.0-todolist

前端开发
2020年10月22日
0

项目环境

  • Node:14.8.0

  • Vue:3.0.0-0

文件目录

bash
├── README.md ├── package-lock.json ├── package.json ├── public │   ├── favicon.ico │   └── index.html ├── src │   ├── App.vue │   ├── assets │   │   └── logo.png │   ├── components │   │   ├── TodoInput.vue │   │   ├── TodoList.vue │   │   └── TodoListItem.vue │   ├── main.ts │   ├── shims-vue.d.ts │   └── store │   └── index.ts └── tsconfig.json

部分代码

store

在 stroe 中,由于项目较小,没有必要使用 vuex,所以使用了 vue3 提供的 provide 以及 inject 来实现状态管理。

  1. 通过 reactive() 生成一个响应式的 todoList 对象;

    js
    // 获取初始化的todoList列表 const getTodoList: () => Array<TodoItem> = () => { let list = []; try { list = JSON.parse(localStorage.getItem('todoList') || '[]'); } catch {} return list; }; export const todoList = reactive(getTodoList());
  2. 对外暴露 useState() 方法,让其它组件可以获取到 todoList 对象;

    js
    export const useState = () => { const todoList = inject(todoListSymbol); return { todoList }; };
  3. 对外暴露 setState(action, options) 方法,让其它组件可以修改 todoList 对象。

    js
    export const setState = async (action: number, options: TodoItem) => { switch (action) { case ACTIONs.CREATE: return await create(options); case ACTIONs.UPDATE: return await update(options); case ACTIONs.REMOVE: return await remove(options); default: throw new Error('Invalid parameter "action"'); } };

App.vue

app.vue 中的 setup() 里面,通过 useState() 来获取 todoList 对象;需要更新列表数据时,则

通过 setState() 来完成。

vue
<script lang="ts"> import { defineComponent, ref } from 'vue'; import { TodoItem, ACTIONs, useState, setState } from '@/store'; import TodoInput from '@/components/TodoInput.vue'; import TodoList from '@/components/TodoList.vue'; export default defineComponent({ name: 'App', components: { TodoInput, TodoList }, setup () { const title = ref(''); const action = ref(ACTIONs.CREATE); const id = ref(''); const { todoList } = useState(); const handleBtnClick = (_type: string, _id: string) => { const item = (todoList as Array<TodoItem>).find((item) => item.id === _id); console.log(_id); if (!item) { alert('程序出错了~'); return false; } switch (_type.toUpperCase()) { case 'UPDATE': action.value = ACTIONs.UPDATE; id.value = _id; title.value = item.title; console.log('here'); break; case 'REMOVE': setState(ACTIONs.REMOVE, item).catch((err) => { alert(err); }); break; default: break; } }; const onInput = (value: string) => { title.value = value; }; const onSubmit = async () => { const value = title.value; console.log('onSubmit.'); if (value.length < 4) { alert('标题不得少于4个字符。'); return false; } const item = (todoList as Array<TodoItem>).find((item) => item.id === id.value); if (!item && action.value === ACTIONs.UPDATE) { alert('非法操作'); return false; } await setState(action.value, { ...item, title: title.value }).catch((err) => { alert(err); }); }; const onCancel = () => { title.value = ''; action.value = ACTIONs.CREATE; }; return { todoList, title, action, onInput, onSubmit, onCancel, handleBtnClick }; } }); </script>

vue3.0-todolist 源码地址