demo.html 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Document</title>
  7. <script src="../babel.min.js"></script>
  8. <script src="../react.development.js"></script>
  9. <script src="../react-dom.development.js"></script>
  10. <link rel="stylesheet" href="./index.css">
  11. </head>
  12. <body>
  13. <div id="root"></div>
  14. <script type="text/babel">
  15. let root = ReactDOM.createRoot(document.getElementById("root"));
  16. function App() {
  17. return <Box />
  18. }
  19. class Box extends React.Component {
  20. constructor() {
  21. super();
  22. this.state = {
  23. todos: [
  24. {
  25. id: 1,
  26. title: "吃饭",
  27. completed: true
  28. },
  29. {
  30. id: 2,
  31. title: "睡觉",
  32. completed: false
  33. },
  34. ],
  35. filters: 'all'
  36. }
  37. this.unChoose = this.unChoose.bind(this);
  38. }
  39. // 添加
  40. addList(val) {
  41. this.setState((prevState) => ({
  42. todos: [
  43. ...prevState.todos,
  44. {
  45. id: Date.now(),
  46. title: val,
  47. completed: false
  48. }
  49. ]
  50. }))
  51. }
  52. // 未选中
  53. unChoose() {
  54. const { todos } = this.state;
  55. return todos.filter((item) => !item.completed).length;
  56. }
  57. // 选中项
  58. chooseMain(val) {
  59. const { todos } = this.state;
  60. this.setState(() => {
  61. for (let i = 0; i < todos.length; i++) {
  62. if (todos[i].id === val) {
  63. todos[i].completed = !todos[i].completed;
  64. }
  65. }
  66. return { todos };
  67. })
  68. }
  69. // 删除选中项
  70. removeItem(val) {
  71. if (!confirm("您确定删除该条数据么!")) return;
  72. const { todos } = this.state;
  73. this.setState((prevState) => ({
  74. todos: prevState.todos.filter((ele) => {
  75. return ele.id !== val
  76. })
  77. }))
  78. }
  79. // 切换状态
  80. setFilters(val) {
  81. console.log(val)
  82. this.setState({
  83. filters: val
  84. })
  85. }
  86. // 全选
  87. allChoose(val){
  88. console.log(val)
  89. const {todos} = this.state;
  90. this.setState((prevState) => ({
  91. todos:prevState.todos.map((item) => {
  92. item.completed = val;
  93. return item
  94. })
  95. }))
  96. }
  97. // 渲染列表
  98. renderList() {
  99. const { todos, filters } = this.state;
  100. if (filters == 'all') return todos;
  101. return todos.filter((item) => filters === 'active' ? !item.completed : item.completed)
  102. }
  103. render() {
  104. return (
  105. <div>
  106. <section className="todoapp">
  107. <Header addMain={this.addList.bind(this)}></Header>
  108. <Main allChoice={this.allChoose.bind(this)} todos={this.renderList()} choose={this.chooseMain.bind(this)} remove={this.removeItem.bind(this)}></Main>
  109. <Footer unChooseMain={this.unChoose()} setFilterMain={this.setFilters.bind(this)} main={this.state.filters}></Footer>
  110. </section>
  111. </div>
  112. )
  113. }
  114. }
  115. function Header({ addMain }) {
  116. return (
  117. <header className="header">
  118. <h1>todos</h1>
  119. <input
  120. autoFocus="autofocus"
  121. autoComplete="off"
  122. placeholder="输入您要完成的任务?"
  123. className="new-todo"
  124. onKeyDown={(e) => {
  125. if (e.keyCode === 13) {
  126. addMain(e.target.value);
  127. e.target.value = '';
  128. }
  129. }}
  130. />
  131. </header>
  132. )
  133. }
  134. function Main({ todos, choose, remove,allChoice }) {
  135. return (
  136. <section className="main">
  137. <input id="toggle-all" type="checkbox" className="toggle-all" onChange={(e)=>allChoice(e.target.checked)} />
  138. <label htmlFor="toggle-all"></label>
  139. <ul className="todo-list">
  140. {todos.map((item) => <Item choice={choose} removeId={remove} todo={item} key={item.id}></Item>)}
  141. </ul>
  142. </section>
  143. )
  144. }
  145. function Footer({ unChooseMain, setFilterMain, main }) {
  146. return (
  147. <footer className="footer">
  148. <span className="todo-count"><strong>{unChooseMain}</strong> items left </span>
  149. <ul className="filters">
  150. <li><a href="#/all" onClick={() => { setFilterMain('all') }} className={main === 'all' ? 'selected' : ''}>All</a></li>
  151. <li><a href="#/active" onClick={() => { setFilterMain('active') }} className={main === 'active' ? 'selected' : ''}>Active</a></li>
  152. <li><a href="#/completed" onClick={() => { setFilterMain('completed') }} className={main === 'completed' ? 'selected' : ''}>Completed</a></li>
  153. </ul>
  154. <button className="clear-completed">Clear completed</button>
  155. </footer>
  156. )
  157. }
  158. function Item({ todo, choice, removeId }) {
  159. return (
  160. <li className="todo">
  161. <div className="view">
  162. <input type="checkbox" className="toggle" onChange={() => choice(todo.id)} checked={todo.completed} />
  163. <label>{todo.title}</label>
  164. <button className="destroy" onClick={() => removeId(todo.id)}></button>
  165. </div>
  166. <input type="text" className="edit" />
  167. </li>
  168. )
  169. }
  170. root.render(<App />);
  171. </script>
  172. </body>
  173. </html>