菜鸟花了一个月,做出一个过得去的ToDoList

18 篇文章 0 订阅

记录一下这个特殊的日子,2020年下半年开始接触React。
这学期开学,老师让我做出点东西给他看,因为只一味地看书是完全不会有进步的,没有自己敲代码出点错误是不会得到进步的。
(优秀的程序猿都是在不断debug中得到成长的,所谓代码一年debug10年就是这样的吧)。
在和老师的一次次交流下,程序一步步变得规范,代码量一步步减少,各种各样的bug也出了,不过最后在秃头日常中,还是对付了过来。

也确实有了很大的收获提升了对React的兴趣,将这段经历分享给是小白的你,咱们共同进步,大佬请自动忽略一个菜鸟的自白,谢谢~。
不摆龙门阵了,接下来进入正题吧。

最终效果展示如下:
可实现删除、添加和完成的基本功能,同时能展示网页刷新时添加事项的时间。
最终效果展示在这里插入图片描述
项目目录结构,TodoList是父组件,TOdoListItem是子组件,总共就分为两个组件。
TodoList部分:

import React, { Component } from 'react';
import TodoListItem from './TodoListItem';
import { getUuid } from './getUuid.js';
import { handleNowTime } from './getTIME';

import './index.css';
const STATUS_ITEM = 0;

class TodoList extends Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [{
        content: "睡觉",
        status: STATUS_ITEM,
        startTime: handleNowTime(new Date()),
        uuid: getUuid()
      },
      {
        content: "做作业",
        status: STATUS_ITEM,
        startTime: handleNowTime(new Date()),
        uuid: getUuid()

      }, {
        content: "学习",
        status: STATUS_ITEM,
        startTime: handleNowTime(new Date()),
        uuid: getUuid()
      }, {
        content: "基于B/S开发的一站式班级管理系统和代码评测系统",
        status: 0,
        startTime: handleNowTime(new Date()),
        uuid: getUuid()
      }
      ],
      finished: 0,
      inputValue: ''
    };
  }
  handleChangeValue = (event) => {
    const { value } = event.target;
    this.setState({
      inputValue: value
    });
  }

  handleAddTask = () => {
    const { inputValue } = this.state;
    if (!inputValue) {
      alert("输入为空,请重新输入待办事项");
      return;
    }
    let nowTime = new Date();
    const startTime = handleNowTime(nowTime);
    let Uuid = getUuid();
    var obj = {
      content: inputValue,
      status: STATUS_ITEM,
      startTime: startTime,
      uuid: Uuid
    };
    const { list } = this.state;
    list.push(obj);
    this.setState({
      list,
      inputValue: ''
    });
  }
  // 更新已完成的事项
  updateFinished = () => {
    const { list } = this.state;
    let finishedTask = 0;
    list.forEach((item) => {
      if (item.status === !STATUS_ITEM) {
        ++finishedTask;
      }
    });
    this.setState({
      finished: finishedTask
    });
  }

  handleClickDelete = (Uuid) => {
    const { list } = this.state;
    const List = list.filter(item =>
      item.uuid !== Uuid);
    this.setState({
      list: List
    });
  }
  enterPress = (event) => {
    if (event.key === 'Enter') {
      this.handleAddTask();
      event.target.value = ''
    }
  }

  render() {
    const { list } = this.state;
    const { finished } = this.state;
    const { inputValue } = this.state;
    return (
      <div className="container">
        <h1>TO DO LIST</h1>
        <hr></hr>
        <div className="listItem">
          <TodoListItem
            list={list}
            handleClickDelete={this.handleClickDelete}
            updateFinished={this.updateFinished}
          />
          <div className="item-count">
            {finished}
            已完成任务/
            {list.length}
            任务总数
          </div>
          <div className="addItem">
            <input
              className="add-input"
              type="text"
              placeholder="Add your item……"
              onKeyPress={this.enterPress}
              value={inputValue}
              onChange={this.handleChangeValue}
            />
            <button className="addButton"
              onClick={this.handleAddTask}
            >
              添加
          </button>
          </div>

        </div>
      </div>
    );
  }
}

export default TodoList;

TodoListItem部分:

import React, { Component } from 'react';

const STATUS_ITEM = 0;
class TodoListItem extends Component {
    constructor(props) {
        super(props);
        this.state = {}
    }
    updateFinished() {
        this.props.updateFinished();
    }
    // 删除任务
    handleClickDelete(Uuid) {
        this.props.handleClickDelete(Uuid);
    }
    // 点击完成事件
    handleClickFinished = (Uuid) => {
        const obj = [];
        const { list } = this.props;
        list.forEach((item) => {
            if (item.uuid === Uuid) {
                if (item.status === STATUS_ITEM) {
                    item.status = !STATUS_ITEM;
                } else {
                    item.status = STATUS_ITEM;
                }
                this.updateFinished();
                this.setState({
                    list: obj
                });
            }
            else {
                obj.push(item);
            }
        })
    }
    listMapItem = (item) => {
        return (
            <div className="warpper"
                key={item.uuid}
            >
                <div className="item">
                    <input type="checkbox"
                        defaultChecked={item.status}
                        onClick={this.handleClickFinished.bind(this, item.uuid)}
                    />
                    <span
                        style={{ textDecorationLine: item.status === STATUS_ITEM ? 'none' : 'line-through' }}
                    >{item.content}
                    </span>
                </div>

                <div className="startTime">
                    {item.startTime}
                </div>
                <button
                    className="delete-button "
                    onClick={this.handleClickDelete.bind(this, item.uuid)}
                >
                    删除
                    </button>
            </div>
        );
    }
    listMap = () => {
        const { list = [] } = this.props;
        return (
            list.map(item => {
                return (this.listMapItem(item))
            })
        )
    }
    render() {
        return (
            <div>
                {this.listMap()}
            </div>
        );
    }
}

export default TodoListItem;

开发日志:
在这里插入图片描述

  • 利用flex布局,尽量少用px单位
  • 改变函数命名模式,使用驼峰命名标准
  • 理清数据流的转态,画图来分析
  • 让代码尽量简洁
  • 尽可能使用箭头函数(需要传参除外,这又是好大一个bug,后来改了)
  • 父子组件里的东西不能乱写
  • render里面的东西更简洁一点,这样利于以后的维护和修改,我的render如此简单
    render() { return ( <div> {this.listMap()} </div> ); }
  • 公共函数应该写在组件外,而不是组件内,增加代码的可移植性和可复用性,减少删改的次数
  • 使用枚举来表示事项状态,不然以后自己都不知道status=0表示什么意思(枚举类型应该使用大写)const STATUS_ITEM = 0;

差不多这些,接下来干DvaJs去了,才有提升……
未完待续……

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 以下是一个简单的 Todo List 的 JavaScript 代码实现: ``` const form = document.querySelector("form"); const input = document.querySelector("input"); const ul = document.querySelector("ul"); form.addEventListener("submit", (event) => { event.preventDefault(); const value = input.value; if (!value) return; const li = document.createElement("li"); li.textContent = value; ul.appendChild(li); input.value = ""; }); ``` 这段代码使用了 HTML 表单、输入框和无序列表来实现 Todo List 的功能。它通过监听表单的 `submit` 事件并使用 `preventDefault` 方法阻止默认的表单提交行为,来实现 Todo List 条目的添加。 ### 回答2: 在使用JavaScript编写一个todolist时,我会使用HTML和CSS来创建页面结构和样式,并通过JavaScript来实现动态添加和删除任务的功能。 首先,我会创建一个输入框和一个提交按钮,用于添加新的任务。用户在输入框中输入任务,点击提交按钮时,会触发一个JavaScript函数。 在JavaScript函数中,我会获取输入框的值,并根据需求进行验证。如果输入框没有值,或者输入的值已存在于任务列表中,我会提醒用户输入有效的任务。 一旦输入的任务通过验证,我会创建一个新的列表项,将其添加到任务列表中。列表项会显示任务的内容以及一个删除按钮。删除按钮会触发另一个JavaScript函数,用于删除对应的任务。 当用户点击删除按钮时,我会找到被点击的按钮的父元素,也就是列表项,在列表中删除这个项,并更新页面上的显示。 此外,我还会添加一个全选按钮和一个清除按钮。全选按钮可以选择或取消选择所有任务,清除按钮可以删除所有已完成的任务。 最后,我会使用本地存储技术,将todolist的任务保存在用户的浏览器中。这样,当用户重新打开页面时,之前添加的任务将会保留下来。 总之,以上就是我用JavaScript编写todolist的大致思路。通过合理的HTML结构、CSS样式和JavaScript功能,可以实现一个简单并实用的todolist。 ### 回答3: 为了使用JavaScript编写一个ToDoList,您需要经历以下步骤: 1. 创建一个HTML文件,包含一个文本输入框用于输入任务,并一个按钮用于添加任务。此外,还需要一个用于显示任务的列表。 2. 在JavaScript文件中,首先使用DOM方法获取所需的HTML元素。例如,使用`getElementById`选择文本输入框和按钮,并使用`querySelector`选择任务列表。 3. 使用事件监听器,为按钮添加点击事件。当按钮被点击时,将触发一个函数。 4. 在该函数中,首先获取输入框中用户输入的任务。可以使用`value`属性获取输入框的值。 5. 创建一个新的列表项元素,并使用`createElement`方法创建一个`li`元素。 6. 将输入框中的任务作为文本内容添加到新创建的`li`元素中。可以使用`innerText`属性设置元素的文本内容。 7. 将新创建的`li`元素添加到任务列表中,可以使用`appendChild`方法将`li`元素添加到任务列表元素中。 8. 清除输入框中的任务,可以使用`value`属性将任务输入框的值设置为空。 9. 重复步骤3到步骤8,以添加更多的任务。 10. 可以为每个任务添加删除功能,当点击任务时,将其从任务列表中移除。可以使用`addEventListener`方法为每个任务添加点击事件监听器,并在监听器函数中使用`removeChild`方法将任务从任务列表中移除。 以上步骤为您提供了一个基本的ToDoList的JavaScript实现框架。您可以根据个人需求和设计进行修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值