Procházet zdrojové kódy

React:添加代办&filters过滤

大侠 před 2 roky
rodič
revize
d17cb733c5
1 změnil soubory, kde provedl 86 přidání a 11 odebrání
  1. 86 11
      15_React/day-3/react-todolist/index.html

+ 86 - 11
15_React/day-3/react-todolist/index.html

@@ -41,6 +41,36 @@
           };
         }
 
+        setFilters(text) {
+          this.setState({
+            filters: text,
+          });
+        }
+
+        addTodo(title) {
+          // 注意:this 必须是 组件实例
+          this.setState((prevState) => ({
+            todos: [
+              ...prevState.todos,
+              { id: Date.now(), title, completed: false },
+            ],
+          }));
+        }
+
+        toggleAllTodoStatus(completed) {
+          // 注意:this 必须是 组件实例
+          this.setState((prevState) => ({
+            todos: prevState.todos.map((todo) => {
+              todo.completed = completed;
+              return todo;
+            }),
+          }));
+        }
+
+        calcUndoneTodoCount() {
+          return this.state.todos.filter((todo) => !todo.completed).length;
+        }
+
         // 根据filters,todos得到过滤后的代办数组
         renderTodos() {
           let { todos, filters } = this.state;
@@ -58,17 +88,25 @@
         }
 
         render() {
+          // console.log(`output->render`);
           return (
             <section className="todoapp">
-              <TodoHeader />
-              <TodoMain todos={this.renderTodos()} />
-              <TodoFooter />
+              <TodoHeader addTodo={this.addTodo.bind(this)} />
+              <TodoMain
+                todos={this.renderTodos()}
+                toggle={this.toggleAllTodoStatus.bind(this)}
+              />
+              <TodoFooter
+                undoneCount={this.calcUndoneTodoCount()}
+                setFilters={this.setFilters.bind(this)}
+                filter={this.state.filters}
+              />
             </section>
           );
         }
       }
 
-      function TodoHeader() {
+      function TodoHeader({ addTodo }) {
         return (
           <header className="header">
             <h1>todos</h1>
@@ -77,14 +115,33 @@
               autoComplete="off"
               placeholder="输入您要完成的任务?"
               className="new-todo"
+              onKeyUp={(e) => {
+                // 判断按下enter
+                // console.log(`output->e`, e);
+                if (e.which === 13) {
+                  let title = e.target.value.trim();
+
+                  if (!title) return alert('您输入的代办名称不合法!');
+
+                  addTodo(title);
+                  e.target.value = '';
+                }
+              }}
             />
           </header>
         );
       }
-      function TodoMain({ todos }) {
+      function TodoMain({ todos, toggle }) {
         return (
           <section className="main">
-            <input id="toggle-all" type="checkbox" className="toggle-all" />
+            <input
+              id="toggle-all"
+              type="checkbox"
+              className="toggle-all"
+              onChange={(e) => {
+                toggle(e.target.checked);
+              }}
+            />
             <label htmlFor="toggle-all"></label>
             <ul className="todo-list">
               {todos &&
@@ -93,25 +150,43 @@
           </section>
         );
       }
-      function TodoFooter() {
+      function TodoFooter({ undoneCount, setFilters, filter }) {
         return (
           <footer className="footer">
             <span className="todo-count">
-              <strong>0</strong> items left
+              <strong>{undoneCount}</strong> items left
             </span>
             <ul className="filters">
               <li>
-                <a href="#/all" className="selected">
+                <a
+                  href="#/all"
+                  className={filter === 'all' ? 'selected' : ''}
+                  onClick={() => {
+                    setFilters('all');
+                  }}
+                >
                   All
                 </a>
               </li>
               <li>
-                <a href="#/active" className="">
+                <a
+                  href="#/active"
+                  className={filter === 'active' ? 'selected' : ''}
+                  onClick={() => {
+                    setFilters('active');
+                  }}
+                >
                   Active
                 </a>
               </li>
               <li>
-                <a href="#/completed" className="">
+                <a
+                  href="#/completed"
+                  className={filter === 'completed' ? 'selected' : ''}
+                  onClick={() => {
+                    setFilters('completed');
+                  }}
+                >
                   Completed
                 </a>
               </li>