index.html 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>代办事项</title>
  8. <script src="./babel.min.js"></script>
  9. <script src="./react.development.js"></script>
  10. <script src="./react-dom.development.js"></script>
  11. <link rel="stylesheet" href="./index.css" />
  12. </head>
  13. <body>
  14. <div id="root"></div>
  15. <script type="text/babel">
  16. function App() {
  17. return (
  18. <>
  19. <TodoApp />
  20. </>
  21. );
  22. }
  23. class TodoApp extends React.Component {
  24. constructor() {
  25. super();
  26. this.state = {
  27. todos: [
  28. {
  29. id: 1,
  30. title: '吃饭',
  31. completed: false,
  32. },
  33. {
  34. id: 2,
  35. title: '睡觉',
  36. completed: true,
  37. },
  38. ], // 所有代办, 默认值 为 []
  39. filters: 'all', // 过滤条件 值为 "all | active | completed", 默认值 all
  40. };
  41. }
  42. // 根据filters,todos得到过滤后的代办数组
  43. renderTodos() {
  44. let { todos, filters } = this.state;
  45. if (filters === 'all') return todos;
  46. // return todos.filter((todo) =>
  47. // filters === 'active'
  48. // ? todo.completed === false
  49. // : todo.completed === true
  50. // );
  51. return todos.filter((todo) =>
  52. filters === 'active' ? !todo.completed : todo.completed
  53. );
  54. }
  55. render() {
  56. return (
  57. <section className="todoapp">
  58. <TodoHeader />
  59. <TodoMain todos={this.renderTodos()} />
  60. <TodoFooter />
  61. </section>
  62. );
  63. }
  64. }
  65. function TodoHeader() {
  66. return (
  67. <header className="header">
  68. <h1>todos</h1>
  69. <input
  70. autoFocus="autofocus"
  71. autoComplete="off"
  72. placeholder="输入您要完成的任务?"
  73. className="new-todo"
  74. />
  75. </header>
  76. );
  77. }
  78. function TodoMain({ todos }) {
  79. return (
  80. <section className="main">
  81. <input id="toggle-all" type="checkbox" className="toggle-all" />
  82. <label htmlFor="toggle-all"></label>
  83. <ul className="todo-list">
  84. {todos &&
  85. todos.map((todo) => <TodoItem key={todo.id} todo={todo} />)}
  86. </ul>
  87. </section>
  88. );
  89. }
  90. function TodoFooter() {
  91. return (
  92. <footer className="footer">
  93. <span className="todo-count">
  94. <strong>0</strong> items left
  95. </span>
  96. <ul className="filters">
  97. <li>
  98. <a href="#/all" className="selected">
  99. All
  100. </a>
  101. </li>
  102. <li>
  103. <a href="#/active" className="">
  104. Active
  105. </a>
  106. </li>
  107. <li>
  108. <a href="#/completed" className="">
  109. Completed
  110. </a>
  111. </li>
  112. </ul>
  113. <button className="clear-completed">Clear completed</button>
  114. </footer>
  115. );
  116. }
  117. function TodoItem({ todo }) {
  118. return (
  119. <li className="todo">
  120. <div className="view">
  121. <input
  122. type="checkbox"
  123. className="toggle"
  124. checked={todo.completed}
  125. />
  126. <label>{todo.title}</label>
  127. <button className="destroy"></button>
  128. </div>
  129. </li>
  130. );
  131. }
  132. const root = ReactDOM.createRoot(document.getElementById('root'));
  133. root.render(<App />);
  134. </script>
  135. </body>
  136. </html>