zheng 22 uur geleden
bovenliggende
commit
4c941f6c05
3 gewijzigde bestanden met toevoegingen van 612 en 0 verwijderingen
  1. 177 0
      19.React/初阶/案例/demo.html
  2. 376 0
      19.React/初阶/案例/index.css
  3. 59 0
      19.React/初阶/案例/index.html

+ 177 - 0
19.React/初阶/案例/demo.html

@@ -0,0 +1,177 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Document</title>
+    <script src="../babel.min.js"></script>
+    <script src="../react.development.js"></script>
+    <script src="../react-dom.development.js"></script>
+    <link rel="stylesheet" href="./index.css">
+</head>
+
+<body>
+    <div id="root"></div>
+    <script type="text/babel">
+        let root = ReactDOM.createRoot(document.getElementById("root"));
+        function App() {
+            return <Box />
+        }
+        class Box extends React.Component {
+            constructor() {
+                super();
+                this.state = {
+                    todos: [
+                        {
+                            id: 1,
+                            title: "吃饭",
+                            completed: true
+                        },
+                        {
+                            id: 2,
+                            title: "睡觉",
+                            completed: false
+                        },
+                    ],
+                    filters: 'all'
+                }
+                this.unChoose = this.unChoose.bind(this);
+            }
+            // 添加
+            addList(val) {
+                this.setState((prevState) => ({
+                    todos: [
+                        ...prevState.todos,
+                        {
+                            id: Date.now(),
+                            title: val,
+                            completed: false
+                        }
+                    ]
+                }))
+            }
+            // 未选中
+            unChoose() {
+                const { todos } = this.state;
+                return todos.filter((item) => !item.completed).length;
+            }
+            // 选中项
+            chooseMain(val) {
+                const { todos } = this.state;
+                this.setState(() => {
+                    for (let i = 0; i < todos.length; i++) {
+                        if (todos[i].id === val) {
+                            todos[i].completed = !todos[i].completed;
+                        }
+                    }
+                    return { todos };
+                })
+            }
+            // 删除选中项
+            removeItem(val) {
+                if (!confirm("您确定删除该条数据么!")) return;
+                const { todos } = this.state;
+                this.setState((prevState) => ({
+                    todos: prevState.todos.filter((ele) => {
+                        return ele.id !== val
+                    })
+                }))
+
+            }
+            // 切换状态
+            setFilters(val) {
+                console.log(val)
+                this.setState({
+                    filters: val
+                })
+            }
+            // 全选
+            allChoose(val){
+                console.log(val)
+                const {todos} = this.state;
+                this.setState((prevState) => ({
+                    todos:prevState.todos.map((item) => {
+                        item.completed = val;
+                        return item
+                    })
+                }))
+            }
+            // 渲染列表
+            renderList() {
+                const { todos, filters } = this.state;
+                if (filters == 'all') return todos;
+                return todos.filter((item) => filters === 'active' ? !item.completed : item.completed)
+            }
+            render() {
+                return (
+                    <div>
+                        <section className="todoapp">
+                            <Header addMain={this.addList.bind(this)}></Header>
+                            <Main allChoice={this.allChoose.bind(this)} todos={this.renderList()} choose={this.chooseMain.bind(this)} remove={this.removeItem.bind(this)}></Main>
+                            <Footer unChooseMain={this.unChoose()} setFilterMain={this.setFilters.bind(this)} main={this.state.filters}></Footer>
+                        </section>
+                    </div>
+                )
+            }
+        }
+        function Header({ addMain }) {
+            return (
+                <header className="header">
+                    <h1>todos</h1>
+                    <input
+                        autoFocus="autofocus"
+                        autoComplete="off"
+                        placeholder="输入您要完成的任务?"
+                        className="new-todo"
+                        onKeyDown={(e) => {
+                            if (e.keyCode === 13) {
+                                addMain(e.target.value);
+                                e.target.value = '';
+                            }
+                        }}
+                    />
+                </header>
+            )
+        }
+        function Main({ todos, choose, remove,allChoice }) {
+            return (
+                <section className="main">
+                    <input id="toggle-all" type="checkbox" className="toggle-all" onChange={(e)=>allChoice(e.target.checked)} />
+                    <label htmlFor="toggle-all"></label>
+                    <ul className="todo-list">
+                        {todos.map((item) => <Item choice={choose} removeId={remove} todo={item} key={item.id}></Item>)}
+                    </ul>
+                </section>
+            )
+        }
+        function Footer({ unChooseMain, setFilterMain, main }) {
+            return (
+                <footer className="footer">
+                    <span className="todo-count"><strong>{unChooseMain}</strong> items left </span>
+                    <ul className="filters">
+                        <li><a href="#/all" onClick={() => { setFilterMain('all') }} className={main === 'all' ? 'selected' : ''}>All</a></li>
+                        <li><a href="#/active" onClick={() => { setFilterMain('active') }} className={main === 'active' ? 'selected' : ''}>Active</a></li>
+                        <li><a href="#/completed" onClick={() => { setFilterMain('completed') }} className={main === 'completed' ? 'selected' : ''}>Completed</a></li>
+                    </ul>
+                    <button className="clear-completed">Clear completed</button>
+                </footer>
+            )
+        }
+        function Item({ todo, choice, removeId }) {
+            return (
+                <li className="todo">
+                    <div className="view">
+                        <input type="checkbox" className="toggle" onChange={() => choice(todo.id)} checked={todo.completed} />
+                        <label>{todo.title}</label>
+                        <button className="destroy" onClick={() => removeId(todo.id)}></button>
+                    </div>
+                    <input type="text" className="edit" />
+                </li>
+            )
+        }
+        root.render(<App />);
+    </script>
+</body>
+
+</html>

+ 376 - 0
19.React/初阶/案例/index.css

@@ -0,0 +1,376 @@
+html,
+body {
+  margin: 0;
+  padding: 0;
+}
+
+button {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  background: none;
+  font-size: 100%;
+  vertical-align: baseline;
+  font-family: inherit;
+  font-weight: inherit;
+  color: inherit;
+  -webkit-appearance: none;
+  appearance: none;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+  font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
+  line-height: 1.4em;
+  background: #f5f5f5;
+  color: #4d4d4d;
+  min-width: 230px;
+  max-width: 550px;
+  margin: 0 auto;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  font-weight: 300;
+}
+
+:focus {
+  outline: 0;
+}
+
+.hidden {
+  display: none;
+}
+
+.todoapp {
+  background: #fff;
+  margin: 130px 0 40px 0;
+  position: relative;
+  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
+}
+
+.todoapp input::-webkit-input-placeholder {
+  font-style: italic;
+  font-weight: 300;
+  color: #e6e6e6;
+}
+
+.todoapp input::-moz-placeholder {
+  font-style: italic;
+  font-weight: 300;
+  color: #e6e6e6;
+}
+
+.todoapp input::input-placeholder {
+  font-style: italic;
+  font-weight: 300;
+  color: #e6e6e6;
+}
+
+.todoapp h1 {
+  position: absolute;
+  top: -155px;
+  width: 100%;
+  font-size: 100px;
+  font-weight: 100;
+  text-align: center;
+  color: rgba(175, 47, 47, 0.15);
+  -webkit-text-rendering: optimizeLegibility;
+  -moz-text-rendering: optimizeLegibility;
+  text-rendering: optimizeLegibility;
+}
+
+.new-todo,
+.edit {
+  position: relative;
+  margin: 0;
+  width: 100%;
+  font-size: 24px;
+  font-family: inherit;
+  font-weight: inherit;
+  line-height: 1.4em;
+  border: 0;
+  color: inherit;
+  padding: 6px;
+  border: 1px solid #999;
+  box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
+  box-sizing: border-box;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+.new-todo {
+  padding: 16px 16px 16px 60px;
+  border: none;
+  background: rgba(0, 0, 0, 0.003);
+  box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03);
+}
+
+.main {
+  position: relative;
+  z-index: 2;
+  border-top: 1px solid #e6e6e6;
+}
+
+.toggle-all {
+  width: 1px;
+  height: 1px;
+  border: none; /* Mobile Safari */
+  opacity: 0;
+  position: absolute;
+  right: 100%;
+  bottom: 100%;
+}
+
+.toggle-all + label {
+  width: 60px;
+  height: 34px;
+  font-size: 0;
+  position: absolute;
+  top: -52px;
+  left: -13px;
+  -webkit-transform: rotate(90deg);
+  transform: rotate(90deg);
+}
+
+.toggle-all + label:before {
+  content: '❯';
+  font-size: 22px;
+  color: #e6e6e6;
+  padding: 10px 27px 10px 27px;
+}
+
+.toggle-all:checked + label:before {
+  color: #737373;
+}
+
+.todo-list {
+  margin: 0;
+  padding: 0;
+  list-style: none;
+}
+
+.todo-list li {
+  position: relative;
+  font-size: 24px;
+  border-bottom: 1px solid #ededed;
+}
+
+.todo-list li:last-child {
+  border-bottom: none;
+}
+
+.todo-list li.editing {
+  border-bottom: none;
+  padding: 0;
+}
+
+.todo-list li.editing .edit {
+  display: block;
+  width: calc(100% - 43px);
+  padding: 12px 16px;
+  margin: 0 0 0 43px;
+}
+
+.todo-list li.editing .view {
+  display: none;
+}
+
+.todo-list li .toggle {
+  text-align: center;
+  width: 40px;
+  /* auto, since non-WebKit browsers doesn't support input styling */
+  height: auto;
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  margin: auto 0;
+  border: none; /* Mobile Safari */
+  -webkit-appearance: none;
+  appearance: none;
+}
+
+.todo-list li .toggle {
+  opacity: 0;
+}
+
+.todo-list li .toggle + label {
+  /*
+		Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433
+		IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/
+	*/
+  background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E');
+  background-repeat: no-repeat;
+  background-position: center left;
+}
+
+.todo-list li .toggle:checked + label {
+  background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E');
+}
+
+.todo-list li label {
+  word-break: break-all;
+  padding: 15px 15px 15px 60px;
+  display: block;
+  line-height: 1.2;
+  transition: color 0.4s;
+}
+
+.todo-list li.completed label {
+  color: #d9d9d9;
+  text-decoration: line-through;
+}
+
+.todo-list li .destroy {
+  display: none;
+  position: absolute;
+  top: 0;
+  right: 10px;
+  bottom: 0;
+  width: 40px;
+  height: 40px;
+  margin: auto 0;
+  font-size: 30px;
+  color: #cc9a9a;
+  margin-bottom: 11px;
+  transition: color 0.2s ease-out;
+}
+
+.todo-list li .destroy:hover {
+  color: #af5b5e;
+}
+
+.todo-list li .destroy:after {
+  content: '×';
+}
+
+.todo-list li:hover .destroy {
+  display: block;
+}
+
+.todo-list li .edit {
+  display: none;
+}
+
+.todo-list li.editing:last-child {
+  margin-bottom: -1px;
+}
+
+.footer {
+  color: #777;
+  padding: 10px 15px;
+  height: 20px;
+  text-align: center;
+  border-top: 1px solid #e6e6e6;
+}
+
+.footer:before {
+  content: '';
+  position: absolute;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  height: 50px;
+  overflow: hidden;
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6,
+    0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6,
+    0 17px 2px -6px rgba(0, 0, 0, 0.2);
+}
+
+.todo-count {
+  float: left;
+  text-align: left;
+}
+
+.todo-count strong {
+  font-weight: 300;
+}
+
+.filters {
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  position: absolute;
+  right: 0;
+  left: 0;
+}
+
+.filters li {
+  display: inline;
+}
+
+.filters li a {
+  color: inherit;
+  margin: 3px;
+  padding: 3px 7px;
+  text-decoration: none;
+  border: 1px solid transparent;
+  border-radius: 3px;
+}
+
+.filters li a:hover {
+  border-color: rgba(175, 47, 47, 0.1);
+}
+
+.filters li a.selected {
+  border-color: rgba(175, 47, 47, 0.2);
+}
+
+.clear-completed,
+html .clear-completed:active {
+  float: right;
+  position: relative;
+  line-height: 20px;
+  text-decoration: none;
+  cursor: pointer;
+}
+
+.clear-completed:hover {
+  text-decoration: underline;
+}
+
+.info {
+  margin: 65px auto 0;
+  color: #bfbfbf;
+  font-size: 10px;
+  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
+  text-align: center;
+}
+
+.info p {
+  line-height: 1;
+}
+
+.info a {
+  color: inherit;
+  text-decoration: none;
+  font-weight: 400;
+}
+
+.info a:hover {
+  text-decoration: underline;
+}
+
+/*
+	Hack to remove background from Mobile Safari.
+	Can't use it globally since it destroys checkboxes in Firefox
+*/
+@media screen and (-webkit-min-device-pixel-ratio: 0) {
+  .toggle-all,
+  .todo-list li .toggle {
+    background: none;
+  }
+
+  .todo-list li .toggle {
+    height: 40px;
+  }
+}
+
+@media (max-width: 430px) {
+  .footer {
+    height: 50px;
+  }
+
+  .filters {
+    bottom: 10px;
+  }
+}

+ 59 - 0
19.React/初阶/案例/index.html

@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>任务清单</title>
+    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
+    <link rel="stylesheet" href="./index.css" />
+  </head>
+  <body>
+    <div id="app">
+      <section class="todoapp">
+        <header class="header">
+          <h1>todos</h1>
+          <input
+            autofocus="autofocus"
+            autocomplete="off"
+            placeholder="输入您要完成的任务?"
+            class="new-todo"
+          />
+        </header>
+        <section class="main">
+          <input id="toggle-all" type="checkbox" class="toggle-all" />
+          <label for="toggle-all"></label>
+          <ul class="todo-list">
+            <li class="todo">
+              <div class="view">
+                <input type="checkbox" class="toggle" />
+                <label>吃饭</label>
+                <button class="destroy"></button>
+              </div>
+              <input type="text" class="edit" />
+            </li>
+          </ul>
+        </section>
+        <footer class="footer">
+          <span class="todo-count"><strong>0</strong> items left </span>
+          <ul class="filters">
+            <li><a href="#/all" class="selected">All</a></li>
+            <li><a href="#/active" class="">Active</a></li>
+            <li><a href="#/completed" class="">Completed</a></li>
+          </ul>
+          <button class="clear-completed">Clear completed</button>
+        </footer>
+      </section>
+      <!-- <footer class="info">
+        <p>就是玩儿</p>
+      </footer> -->
+    </div>
+
+    <script>
+      new Vue({
+        el: '#app',
+        data: {},
+      });
+    </script>
+  </body>
+</html>