记录:vue3.0-todolist
项目环境
-
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
来实现状态管理。
-
通过
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());
-
对外暴露
useState()
方法,让其它组件可以获取到 todoList 对象;jsexport const useState = () => { const todoList = inject(todoListSymbol); return { todoList }; };
-
对外暴露
setState(action, options)
方法,让其它组件可以修改 todoList 对象。jsexport 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>