<body>
  <div id="count"></div>
  <button id="button">click</button>
</body>
// ビジネスロジックを扱うモデルクラス
class Model {
  constructor() {
    this.count = 0;
  } 
  // 2. カウンタをインクリメント
  increment() {
    this.count++;
    this.trigger();
  }
  // 3. データが更新されたことを知らせるイベントで発行
  trigger() {
    const event = new CustomEvent("count/increment", { count: this.count })
    window.dispatchEvent(event);
  }
}

// ビューとコントローラを扱うクラス
class ViewController {
  constructor() {
    this.model = new Model();
    this.element = document.getElementById("count");
    this.button = document.getElementById("button");
  }
  mount() {
    this.render();
    // クリックした時のイベント登録(インクリメントするメソッドを呼び出す)
    this.button.addEventListener("click", (e) => this.onClick(e));
    // インクリメントした後のイベント登録(メッセージを描画)
    window.addEventListener("count/increment", (e) => this.onMessage(e));
  }
  render() {
    this.element.innerHTML = `<p>${this.model.count}</P>`
  }
  // 4. インクリメントされたら、画面をレンダリング
  onMessage() {
    this.render();
  }
  // 1. ボタンをクリックされたらモデルに対してインクリメントする処理を実行
  onClick(event) {
    this.model.increment();
  }
}

const view = new ViewController();
view.mount();

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.