快速起步一个简单JsApp

“一般思路”

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Hello, world!</title>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
  </head>
  <body>
    <div class="Counter">
      <button class="CounterSub">-</button>
      <span class="CounterNum">0</span>
      <button class="CounterAdd">+</button>
    </div>

    <script>
      const $ = {
        sub: document.querySelector('.CounterSub'),
        add: document.querySelector('.CounterAdd'),
        num: document.querySelector('.CounterNum'),
      };

      $.sub.addEventListener('click', (event) => {
        $.num.textContent = parseInt($.num.textContent, 10) - 1;
      });

      $.add.addEventListener('click', (event) => {
        $.num.textContent = parseInt($.num.textContent, 10) + 1;
      });
    </script>
  </body>
</html>

“改数据,界面变” v1

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Hello, world!</title>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
  </head>
  <body>
    <div class="Counter">
      <button class="CounterSub">-</button>
      <span class="CounterNum">0</span>
      <button class="CounterAdd">+</button>
    </div>

    <script>
      // *** State ***

      const state = {
        count: 0,
      };

      function setState(newState) {
        Object.assign(state, newState);
        render();
        afterRender();
      }
      
      // *** DOM & Logic ***

      const $ = {
        sub: document.querySelector('.CounterSub'),
        add: document.querySelector('.CounterAdd'),
        num: document.querySelector('.CounterNum'),
      };
      
      (function didMount() {
        console.log('didMount');
        $.sub.addEventListener('click', (event) => setState({ count: state.count - 1 }));
        $.add.addEventListener('click', (event) => setState({ count: state.count + 1 }));
      })()
      
      function render() {
        console.log('render');
        $.num.textContent = state.count;
      }
      
      function afterRender() {
        console.log('afterRender');
      }
      
      // *** Main ***

      render();
    </script>
  </body>
</html>

“改数据,界面变” v2

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Hello, world!</title>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
  </head>
  <body>
    <div class="Counter">
      <button class="CounterSub">-</button>
      <span class="CounterNum">0</span>
      <button class="CounterAdd">+</button>
    </div>

    <script>
      // *** State ***

      const initialState = {
        count: 0,
      };

      const stateHandler = {
        set: (o, p, v) => {
          const res = Reflect.set(o, p, v);
          render();
          afterRender();
          return res;
        }
      };

      const state = new Proxy(initialState, stateHandler);
      
      // *** DOM & Logic ***

      const $ = {
        sub: document.querySelector('.CounterSub'),
        add: document.querySelector('.CounterAdd'),
        num: document.querySelector('.CounterNum'),
      };
      
      (function didMount() {
        console.log('didMount');
        $.sub.addEventListener('click', (event) => state.count--);
        $.add.addEventListener('click', (event) => state.count++);
      })()
      
      function render() {
        console.log('render');
        $.num.textContent = state.count;
      }
      
      function afterRender() {
        console.log('afterRender');
      }
      
      // *** Main ***

      render();
    </script>
  </body>
</html>

知识点:

  1. Proxy + Reflect