demo.html 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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. const root = ReactDOM.createRoot(document.getElementById("root"));
  16. function App() {
  17. return (
  18. <div>
  19. <Box />
  20. </div>
  21. )
  22. }
  23. class Box extends React.Component {
  24. constructor() {
  25. super();
  26. this.state = {
  27. todos: [
  28. {
  29. id: 1,
  30. title: '吃饭',
  31. completed: true
  32. },
  33. {
  34. id: 2,
  35. title: '睡觉',
  36. completed: false
  37. }
  38. ],
  39. filters: "all"
  40. }
  41. this.unChooseThing = this.unChooseThing.bind(this);
  42. }
  43. unChooseThing() {
  44. // 过滤出未选中的数量
  45. // 通过判断每一项中的completed字段 如果是false就是未选择
  46. // 数组中数据是不确定的 但是每一条都需要去判断 所以进行循环
  47. // 对每一条都进行过滤
  48. // this.state.todos
  49. let { todos } = this.state;
  50. return todos.filter((item) => !item.completed).length;
  51. }
  52. chooseThing(val) {
  53. console.log(val);
  54. let { todos } = this.state;
  55. this.setState(() => {
  56. for (let i = 0; i < todos.length; i++) {
  57. if (todos[i].id === val) {
  58. todos[i].completed = !todos[i].completed;
  59. }
  60. }
  61. return { todos }
  62. })
  63. }
  64. addTodos(val) {
  65. console.log("按下", val)
  66. this.setState((prevState) => ({
  67. todos: [
  68. ...prevState.todos,
  69. {
  70. id: Date.now(),
  71. title: val,
  72. completed: false
  73. }
  74. ]
  75. }))
  76. }
  77. changeFilter(val) {
  78. this.setState({
  79. filters: val
  80. })
  81. }
  82. renderList() {
  83. let {todos,filters} = this.state;
  84. if(filters == 'all') return todos;
  85. // else if (filters == 'active') {
  86. // return todos.filter((item) => item.completed == false)
  87. // } else {
  88. // return todos.filter((item) => item.completed == true)
  89. // }
  90. return todos.filter((item) => filters === 'active' ? !item.completed : item.completed)
  91. }
  92. clearThing(val) {
  93. if(!confirm("您确定删除该条数据么?")) return;
  94. let {todos} = this.state;
  95. this.setState((prevState) =>({
  96. todos: prevState.todos.filter((item)=> item.id !== val)
  97. }))
  98. }
  99. toggle(val) {
  100. console.log(val)
  101. const {todos} = this.state;
  102. this.setState((prevState) => ({
  103. todos:prevState.todos.map((item)=> {
  104. item.completed = val;
  105. return item;
  106. })
  107. }))
  108. }
  109. render() {
  110. return (
  111. <section className="todoapp">
  112. <Header addThing={this.addTodos.bind(this)} />
  113. <Main
  114. todos={this.renderList()}
  115. handleChoose={this.chooseThing.bind(this)}
  116. remove={this.clearThing.bind(this)}
  117. toggleThing={this.toggle.bind(this)}
  118. />
  119. <Footer unChoose={this.unChooseThing()} filter={this.state.filters} setFilter={this.changeFilter.bind(this)} />
  120. </section>
  121. )
  122. }
  123. }
  124. function Header({ addThing }) {
  125. return (
  126. <header className="header">
  127. <h1>todos</h1>
  128. <input
  129. autoFocus="autofocus"
  130. autoComplete="off"
  131. placeholder="输入您要完成的任务?"
  132. className="new-todo"
  133. onKeyDown={(e) => {
  134. if (e.keyCode == 13) {
  135. addThing(e.target.value)
  136. }
  137. e.target.value = '';
  138. }}
  139. />
  140. </header>
  141. )
  142. }
  143. function Main({ todos, handleChoose,remove,toggleThing }) {
  144. console.log(todos, '121')
  145. return (
  146. <section className="main">
  147. <input id="toggle-all" type="checkbox" className="toggle-all" onChange={(e)=>toggleThing(e.target.checked)} />
  148. <label htmlFor="toggle-all"></label>
  149. <ul className="todo-list">
  150. {
  151. todos && todos.map((item) => { return <Only key={item.id} todo={item} choose={handleChoose} removeThing={remove} /> })
  152. }
  153. </ul>
  154. </section>
  155. )
  156. }
  157. function Footer({ unChoose,filter,setFilter }) {
  158. return (
  159. <footer className="footer">
  160. <span className="todo-count"><strong>{unChoose}</strong> items left </span>
  161. <ul className="filters">
  162. <li><a href="#/all" className={filter == 'all' ? 'selected' : ''} onClick={()=>{
  163. setFilter('all')
  164. }}>All</a></li>
  165. <li><a href="#/active" className={filter == 'active' ? 'selected' : ''} onClick={()=>{
  166. setFilter('active')
  167. }}>Active</a></li>
  168. <li><a href="#/completed" className={filter == 'completed' ? 'selected' : ''} onClick={()=>{
  169. setFilter('completed')
  170. }}>Completed</a></li>
  171. </ul>
  172. <button className="clear-completed">Clear completed</button>
  173. </footer>
  174. )
  175. }
  176. function Only({ todo, choose,removeThing }) {
  177. return (
  178. <li className="todo">
  179. <div className="view">
  180. <input type="checkbox" checked={todo.completed}
  181. onChange={() => choose(todo.id)} className="toggle" />
  182. <label>{todo.title}</label>
  183. <button className="destroy" onClick={()=>{
  184. removeThing(todo.id)
  185. }}></button>
  186. </div>
  187. <input type="text" className="edit" />
  188. </li>
  189. )
  190. }
  191. root.render(<App />);
  192. </script>
  193. </body>
  194. </html>