vue3实现一个todo?list,博智网带你了解详细信息。
目录
- 功能介绍
- 相关代码
- 总结
实现方式不是最优,主要是为了学习vue3的一些新语法以及属性
功能介绍
相关代码
index.vue
<template> <p class="todo-list"> <el-card class="box-card"> <template #header> <p class="card-header"> <span>工作计划</span> <el-button class="button" type="primary" icon="el-icon-circle-plus" circle @click="handleClickTodo" ></el-button> </p> </template> <template v-if="list.length > 0"> <todo-item v-for="(val, index) in list" :key="index" :info="val" ></todo-item> </template> <el-empty v-else description="还没有待办的事项~"></el-empty> </el-card> <add-action v-model:visible="visible"></add-action> </p> </template> <script> import AddAction from "./AddTodo.vue"; import TodoItem from "./Item.vue"; import { reactive, toRefs, provide } from "vue"; export default { name: "todo-list", components: { AddAction, TodoItem }, setup() { const state = reactive({ visible: false, list: [ { title: "1.学习vue3.0", time: "2021-08-20", desc: "1.ppppppppppppp", status: false, }, ], }); const addTodo = (data) => { state.list.push(data); }; const delTodo = (title) => { state.list = state.list.filter((val) => val.title !== title); }; const handleClickTodo = () => { state.visible = true; }; provide("addTodo", addTodo); provide("delTodo", delTodo); return { handleClickTodo, ...toRefs(state), }; }, }; </script> <style> .todo-list { padding: 100px; } .card-header { display: flex; justify-content: space-between; align-items: center; } .text { font-size: 14px; } .item { margin-bottom: 18px; } .box-card { width: 480px; } </style>
AddTodo.vue
<template> <el-dialog title="新增待办计划" v-model="visible" width="600px" @close="handleClose" > <el-form style="width: 430px" :model="form" :rules="rules" label-width="120px" ref="formRef" > <el-form-item label="计划名称" prop="title"> <el-input v-model="form.title" placeholder="请输入待办计划名称" ></el-input> </el-form-item> <el-form-item label="计划完成时间" prop="time"> <el-date-picker value-format="YYYY/MM/DD" style="width: 100%" v-model="form.time" type="date" placeholder="请选择计划完成时间"> </el-date-picker> </el-form-item> <el-form-item label="计划详细描述" prop="desc"> <el-input type="textarea" :rows="6" v-model="form.desc" placeholder="请输入详细待办计划" ></el-input> </el-form-item> </el-form> <template #footer> <span class="dialog-footer"> <el-button @click="visible = false">取 消</el-button> <el-button type="primary" @click="handleConfirm">确 定</el-button> </span> </template> </el-dialog> </template> <script> import { reactive, toRefs, ref, inject } from "vue"; export default { name: "add-todo", props: { visible: { type: Boolean, default: false, }, }, setup(props, { emit }) { const formRef = ref(null) const addTodo = inject('addTodo') const state = reactive({ form: { title: "", desc: "", time: "", status: false }, rules: { title: [ { required: true, message: '请输入待办计划名称', trigger: ['blur']} ], time: [ { required: true, message: '请选择待办计划时间', trigger: ['change']} ], desc: [ { required: true, message: '请输入详细待办计划', trigger: ['blur']} ] }, }); const handleClose = () => { emit("update:visible", false); formRef.value.clearValidate() formRef.value.resetFields() }; const handleConfirm = () => { formRef.value.validate(valid => { if (valid) { addTodo(JSON.parse(JSON.stringify(state.form))) handleClose() } }) } return { formRef, ...toRefs(state), handleClose, handleConfirm }; }, }; </script>
Item.vue
<template> <p class="todo-item"> <p class="titme-box"> <el-checkbox v-model="info.status" @click="change"></el-checkbox> <h3 :class="info.status ? 'success' : ''">{{ info.title }}</h3> </p> <p class="del"> <p class="time" :class="info.status ? 'success' : ''">{{ info.time }}</p> <el-button type="danger" icon="el-icon-delete" circle size="mini" @click="handleDelTodo" ></el-button> </p> </p> </template> <script> import { inject } from "vue"; export default { name: "todo-item", props: { info: { type: Object, default: () => ({}), }, }, setup(props) { const delTodo = inject("delTodo"); const handleDelTodo = () => { delTodo(props.info.title); }; return { handleDelTodo, }; }, }; </script> <style lang="scss"> .todo-item { display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid rgb(229, 226, 226); height: 45px; line-height: 45px; .success { text-decoration: line-through; } .titme-box { display: flex; align-items: center; h3 { padding-left: 12px; font-size: 16px; } } .del { display: flex; align-items: center; .time { width: 100px; font-size: 14px; } } } </style>
总结
本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注趣讯吧的更多内容!