• todolist-react版(9.20-9.21)


    # 设计效果

     

    一. 框架
    设计一个todolist,可以添加并记录今天做的事情,分为未完成和已完成,并且每个记录可以删除,并且统计记录总数和完成的数量
    # 数据结构
    父组件todoList包括输入框添加组件和列表数据组件
    # 组件划分
    todoList组件/输入框添加组件/列表数据组件
    # 具体实现
    父组件list
      把添加任务部分和列表部分记录数据集合起来,用来实现添加任务,更新任务总数,完成任务总数
      1. 父组件标题是ToDoList, h1, 未完成的样式,背景颜色#DFFCB5,color 颜色 #2EB872,完成样式,背景颜色#FFFA9D,颜色#FF9A3C,删除线 textDecoration: 'line-through'
      2. 初始化时设置列表list的默认数据及初始化完成数量参数
      3. 父组件添加任务方法更新任务列表list;完成任务状态改变时更新完成数量并更新;更新总数方法当删除时更新总数及对象传出去.
      4. render(){return ()},dom包括标题/列表数据需要通过map来遍历/完成数和总数
    列表item组件
      勾选完成和删除数据,显示列表数据
     1. 处理完成的任务,完成时需要切换状态,并把id,名称,状态等数据通过props传出去
     2. 删除把props接收到的item传出去,组件那里需要通过item={item}来接收
     3. render(){return ()},dom来处理完成和未完成样式及勾选框/名称/删除按钮
     4. 初始化时绑定事件,如this.handleFinished = this.handleFinished.bind(this)
    输入任务,添加任务组件
      给input输入框绑定ref事件,添加任务判断任务列表个数来设置id,添加任务并清空输入框
     1. 添加任务,通过绑定ref来获取到输入框的值并判断值是否为空,如为空提示信息并返回,否则添加任务,添加任务时通过props获取到列表总数来设置id,如果列表总数大于0,id取列表总数值否则为0,如果输入框存在且值不为空时,设置对象id/name(输入框的值)/状态,清空输入框的值,通过props添加任务
     2. render(){return ()},dom Task子标题,输入框绑定ref,按钮处理添加任务
     # 样式分析
     父组件 container 
    
     # 复盘应用到的知识
     1. react 实现构造方法constructor,必须实现super();
     2. react 绑定ref 需要建立ref,例子 this.myText = React.createRef(),dom ref={this.myText}.
     3. react的事件需要绑定的,例子 处理单击事件this.handleClick = this.handleClick.bind(this).
     4. 获取input的值,需要获取到current对象中的value.
     5. 调用父组件方法,例子this.props.addNewTask(obj),调用父组件的值 this.props.item.status.
     6. 调用state中的值,this.state, 更新state,this.setState({name: 'sdf'}).
     7. react render (){} 函数中可以添加变量以方便在return()中使用
     8. react 设置样式有两种,一是通过className="name",另一个种是style={style},style是一个对象,每个样式结束用逗号隔开.
     9. 在react 中遍历数组时用map,且组件也就是=>后面的组件不需要用{}来包裹
     10. 媒体尺寸适配, 
     @media screen and (max- 767px) {
       .container {
         ...
       }
       h3 {
         ....
       }
     }
    

     上代码如下:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>ToDoList</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="./main.css">
        <script src="../Build/react.development.js"></script>
        <script src="../Build/react-dom.development.js"></script>
        <script src="../Build/babel.min.js"></script>
      </head>
      <body>
        <div id="app"></div>
        <script type="text/babel">
          // todolist 输入框
          class Dialog extends React.Component {
            constructor (props) {
              super(props)
              this.myText = React.createRef();
              this.handleClick = this.handleClick.bind(this);
            }
            handleClick () {
              if (!this.myText.current.value) {
                alert('请添加你的任务')
                return 
              }
              const len = this.props.nums;
              const newId = len > 0 ? len : 0;
              const value = this.myText.current.value;
              if (!value !== '') {
                const obj = {
                  id: newId,
                  name: value,
                  status: 0
                };
                this.myText.current.value = '';
                this.props.addNewTask(obj);
              }
            }
            render () {
              return (
                <div className="dialog">
                  <div>
                    <h3>Task</h3>
                    <input type="text" placeholder="今天做什么" ref={this.myText}/>
                    <input type="button" value="添加" onClick={this.handleClick}/>
                  </div>
                </div>
              )
            }
          }
          // listItem
          class ListItem extends React.Component {
            constructor(props) {
              super(props)
              this.handleFinished = this.handleFinished.bind(this)
              this.handleDelete = this.handleDelete.bind(this)
            }
            // 处理todolist完成
            handleFinished () {
              let status = this.props.item.status
              status = (status === 0 ? 1 : 0)
              let obj = {
                id: this.props.item.id,
                name: this.props.item.name,
                status: status
              }
              this.props.finishChange(obj)
            }
            // 删除todolist一项
            handleDelete () {
              this.props.totalChange(this.props.item)
            }
            render () {
              const item = this.props.item
              const unfinish = {
                backgroundColor: '#DFFCB5',
                color: '#2EB872'
              }
              const finish = {
                backgroundColor: '#FFFA9D',
                color: '#FF9A3C',
                textDecoration: 'line-through'
              }
              var itemStyle = item.status === 0 ? unfinish : finish;
              return (
                <li key={item.id} style={itemStyle}>
                  <span onClick={this.handleFinished}
                  id={item.id}
                  className="check-btn"
                  style={{backgroundColor: item.status === 0 ? '#fff': '#A1EAFB'}}>
                  </span>
                  <span>{item.name}</span>
                  <span onClick={this.handleDelete} className="delete-btn">删除</span>
                </li>
              )
            }
          }
          // 数组
          class ToDoList extends React.Component {
            constructor(props) {
              super(props)
              this.state = {
                list: [{
                  id: 0,
                  name: 'react学习',
                  status: 0
                }, {
                  id: 1,
                  name: 'vue学习',
                  status: 0
                }],
                finished: 0
              }
            }
            addTask (newItem) {
              var allTask = this.state.list;
              allTask.push(newItem)
              this.setState({
                list: allTask
              });
            }
            updateFinished (todoItem) {
              console.log('------------updateFinished', todoItem);
              var sum = 0;
              this.state.list.forEach((item) => {
                if (item.id === todoItem.id) {
                  item.status = todoItem.status;
                }
                if (item.status === 1) {
                  sum++;
                }
              });
              this.setState({
                finished: sum
              })
            }
            updateTotal (todoItem) {
              var obj = []
              var sum = 0
              this.state.list.forEach((item) => {
                if (item.id !== todoItem.id) {
                  obj.push(item)
                  if (item.status === 1) {
                    sum++
                  }
                }
              })
              this.setState({
                list: obj,
                finished: sum
              })
            }
            render () {
              return (
                <div className="container">
                  <h1>toDoList</h1>
                  <Dialog addNewTask={this.addTask.bind(this)} nums={this.state.list.length}/>
                  <ul>
                    {
                      this.state.list.map((item, index) => 
                        <ListItem
                          item={item}
                          finishChange={this.updateFinished.bind(this)}
                          totalChange={this.updateTotal.bind(this)}
                          key={index}>
                        </ListItem>
                      )
                    }
                    <li>{this.state.finished}已完成 / {this.state.list.length}总数</li>
                  </ul>
                </div>
              )
            }
          }
          ReactDOM.render(
            <ToDoList/>,
            document.getElementById('app')
          )
        </script>
      </body>
    </html>
    
    // main.css
    .container {
    	text-align: center;
    	background-color: #f7f7f7;
    	margin: 50px 20%;
    	padding: 20px 0;
    	height: 100%;
    	border-radius: 5px;
    }
    
    .dialog {
    	text-align: left;
    	margin: 0 5%;
    	padding: 30px 0;
    }
    
    .dialog div {
    	/* overflow: hidden; */
    	display: flex;
    	justify-content: center;
    	align-items: center;
    }
    
    h3 {
    	display: inline-block;
    	margin-left: 50px;
    	margin-right: 20px;
    	/* position: relative;
    	top: 50%;
    	transform: translateY(-50%); */
    }
    
    input[type="text"] {
    	line-height: 40px;
    	/* float: right; */
    	 80%;
    	border-radius: 5px;
    	border: none;
    	font-size: 16px;
    	box-sizing: border-box;
    	padding: 0 5px;
    	border: 1px #ccc solid;
    	outline: none;
    	box-shadow: 0 0 10px #ccc;
    }
    
    input[type="button"] {
    	margin-left: 20px;
    	border: none;
    	background-color: #A1EAFB;
    	height: 40px;
    	 110px;
    	font-size: 18px;
    	color: #fff;
    	border-radius: 5px;
    	/* float: right; */
    }
    
    ul {
    	text-align: left;
    	margin: 20px 5%;
    	border-radius: 5px;
    	border: 1px #bbb solid;
    }
    
    ul li {
    	list-style: none;
    	line-height: 50px;
    	border-bottom: 1px #bbb solid;
    	padding: 0 20px;
    }
    
    ul li:first-child {
    	/* border-top-left-radius: 5px;
    	border-top-right-radius: 5px; */
    }
    
    ul li:last-child {
    	/* border-bottom-left-radius: 5px;
    	border-bottom-right-radius: 5px; */
    }
    
    ul li:hover > .delete-btn {
    	display: block;
    }
    
    .delete-btn {
    	color: #ccc;
    	float: right;
    	cursor: pointer;
    	display: none;
    }
    
    .check-btn {
    	 13px;
    	height: 13px;
    	display: inline-block;
    	border: 1px #ccc solid;
    	border-style: outset;
    	border-radius: 5px;
    	margin-right: 20px; 
    	cursor: pointer;
    }
    /* 
    input[type="checkbox"] {
    	border: 0;
    	color: #fff;
    	background-color: #A1EAFB;
    } */
    
    @media screen and (max- 767px) {
    	.container {
    		margin: 20px 5%;
    	}
    
    	h3 {
    		margin-left: 0;
    	}
    
    

      

     

    将来的自己,会感谢现在不放弃的自己!
  • 相关阅读:
    实现一个WEBIM
    拼写纠错
    UML系列图用例图
    [bzoj1670][Usaco2006 Oct]Building the Moat
    [bzoj3626][LNOI2014]LCA
    转:用JS写的一个树型结构
    一个购物车中修改商品数量的实列
    网站访问统计在Global.asax中的配置的深入讨论
    转:JavaScript中的三级联动
    转:用Sql Server存储上载图片字体
  • 原文地址:https://www.cnblogs.com/TheYouth/p/15317822.html
Copyright © 2020-2023  润新知