vue3實現一個todo-list
實現方式不是最優,主要是為瞭學習vue3的一些新語法以及屬性
功能介紹
相關代碼
index.vue
<template> <div class="todo-list"> <el-card class="box-card"> <template #header> <div class="card-header"> <span>工作計劃</span> <el-button class="button" type="primary" icon="el-icon-circle-plus" circle @click="handleClickTodo" ></el-button> </div> </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> </div> </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> <div class="todo-item"> <div class="titme-box"> <el-checkbox v-model="info.status" @click="change"></el-checkbox> <h3 :class="info.status ? 'success' : ''">{{ info.title }}</h3> </div> <div 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> </div> </div> </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>
總結
本篇文章就到這裡瞭,希望能給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!
推薦閱讀:
- vue3中如何使用ts
- vue 動態添加el-input的實現邏輯
- 如何理解Vue簡單狀態管理之store模式
- 總結Vue Element UI使用中遇到的問題
- vue element實現表格增加刪除修改數據