vue3实现一个todo-list

实现方式不是最优,主要是为了学习vue3的一些新语法以及属性,各位大佬勿喷~

功能介绍

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

项目的搭建可以参考这篇文章

vue3.x+vite+element-ui+vue-router+vuex+axios搭建项目

相关代码

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>

在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是使用Vue.js创建一个Todo List应用的步骤: 1. 创建Vue.js应用程序 你可以使用Vue CLI来创建一个新的Vue.js应用程序。打开终端并输入以下命令: ``` vue create todo-list ``` 这将创建一个名为“todo-list”的新Vue.js应用程序,并在其中包含所有必要的文件和依赖项。 2. 创建Todo组件 在src文件夹下创建一个名为“components”的新文件夹,并在其中创建一个名为“Todo.vue”的新文件。在这个文件中,你可以创建一个新的Vue组件,用于渲染Todo List应用程序的界面。 ```html <template> <div> <h1>Todo List</h1> <form v-on:submit.prevent="addTodo"> <input v-model="newTodo" placeholder="Add a new todo"> <button type="submit">Add</button> </form> <ul> <li v-for="(todo, index) in todos" v-bind:key="index"> <input type="checkbox" v-model="todo.completed"> <span v-bind:class="{ completed: todo.completed }">{{ todo.text }}</span> <button v-on:click="deleteTodo(index)">Delete</button> </li> </ul> </div> </template> <script> export default { data() { return { newTodo: '', todos: [] } }, methods: { addTodo() { if (this.newTodo.trim()) { this.todos.push({ text: this.newTodo, completed: false }) this.newTodo = '' } }, deleteTodo(index) { this.todos.splice(index, 1) } } } </script> <style> .completed { text-decoration: line-through; } </style> ``` 在这个组件中,我们定义了一个名为“newTodo”的data属性,用于存储新的Todo项的文本内容。我们还定义了一个名为“todos”的data属性,用于存储所有的Todo项。在template中,我们使用v-for指令来遍历todos数组,并为每个Todo项渲染一个li元素。我们还使用v-bind指令来将每个Todo项的completed属性绑定到一个复选框上,以便用户可以标记已完成的Todo项。最后,我们还定义了两个方法:addTodo方法用于添加新的Todo项,deleteTodo方法用于删除现有的Todo项。 3. 在应用程序中使用Todo组件 打开src文件夹下的“App.vue”文件,并将Todo组件导入到该文件中。然后在template中使用Todo组件。 ```html <template> <div id="app"> <Todo /> </div> </template> <script> import Todo from './components/Todo.vue' export default { name: 'app', components: { Todo } } </script> ``` 4. 运行应用程序 现在你可以运行应用程序并查看Todo List应用程序的界面。在终端中输入以下命令: ``` npm run serve ``` 这将启动开发服务器,并在浏览器中打开Todo List应用程序。你可以添加新的Todo项,并标记已完成的Todo项。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值