HTMLにVueを足す

前章で作ったHTMLにVue.jsを導入します.
必要なのはImport Map<script type="module"> だけです.

<script type="importmap">
  {
    "imports": {
      "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
    }
  }
</script>
<script type="module">
  import { createApp } from "vue";
  // ...
</script>

npm installnode_modulespackage.jsonも不要.
ブラウザのネイティブESM (ES Modules)を使って,Vueをimportするだけです.

Import Mapとは

Import Mapは,ブラウザに「'vue'という名前は,このURLのことだよ」と教える仕組みです.
Node.jsのnode_modulesに相当するものを,HTMLの <script> タグで宣言できます.

Vueアプリケーションを作る

Vueを読み込んだら,アプリケーションを作ってHTMLにマウントします.

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>My App</title>
    <style>
      body {
        font-family: sans-serif;
        max-width: 600px;
        margin: 40px auto;
        padding: 0 20px;
      }
      .card {
        border: 1px solid #e2e8f0;
        border-radius: 8px;
        padding: 20px;
        margin-bottom: 16px;
      }
      .card h2 {
        margin-top: 0;
      }
      .tag {
        display: inline-block;
        background: #edf2f7;
        border-radius: 4px;
        padding: 2px 8px;
        font-size: 0.85em;
        margin-right: 4px;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <h1>My Bookshelf</h1>
      <p>最近読んだ本の記録です.</p>

      <div class="card">
        <h2>リーダブルコード</h2>
        <p>読みやすいコードを書くための実践的な技法.</p>
        <span class="tag">programming</span>
        <span class="tag">practices</span>
      </div>

      <div class="card">
        <h2>プログラミング言語の基礎概念</h2>
        <p>言語の設計を支える根本的な概念を学ぶ.</p>
        <span class="tag">cs</span>
        <span class="tag">language</span>
      </div>

      <div class="card">
        <h2>Web ブラウザセキュリティ</h2>
        <p>ブラウザに関するセキュリティを体系的に解説.</p>
        <span class="tag">security</span>
        <span class="tag">browser</span>
      </div>
    </div>

    <script type="importmap">
      {
        "imports": {
          "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
        }
      }
    </script>
    <script type="module">
      import { createApp } from "vue";

      createApp({}).mount("#app");
    </script>
  </body>
</html>

ブラウザで開いてみてください.見た目は前章とまったく同じ です.

これが"Progressive"の意味です.
Vueを導入しても,既存のHTMLは壊れません.
<div id="app"> で囲んで,createApp({}).mount('#app')するだけ.
アプリケーションの「マウントポイント」を指定しただけで,中身のテンプレートはそのまま ただのHTMLとして残っています.

データをJavaScriptに移す

ここからがVueの出番です.
HTMLにベタ書きされていたデータを,JavaScriptで管理するようにします.

Vueのref() を使って リアクティブなデータ を作ります.

<script type="module">
  import { createApp, ref } from "vue";

  createApp({
    setup() {
      const books = ref([
        {
          title: "リーダブルコード",
          description: "読みやすいコードを書くための実践的な技法.",
          tags: ["programming", "practices"],
        },
        {
          title: "プログラミング言語の基礎概念",
          description: "言語の設計を支える根本的な概念を学ぶ.",
          tags: ["cs", "language"],
        },
        {
          title: "Web ブラウザセキュリティ",
          description: "ブラウザに関するセキュリティを体系的に解説.",
          tags: ["security", "browser"],
        },
      ]);

      return { books };
    },
  }).mount("#app");
</script>

setup() 関数の中でref() を使ってデータを定義し,returnでテンプレートに公開します.
return { books } — テンプレートからbooksという名前でアクセスできるようになります.

でも今はまだ,テンプレート側でこのデータを使っていません.
次の章でそれをやります.

ここまでの構造

ここで一歩引いて,今のファイル構成を確認しましょう.

index.html   ← これだけ

ファイルは 一つだけ です.
フレームワークはCDNからESMで読み込んでいます.
ビルドステップはありません.
ローカルサーバーすら不要です(ファイルをダブルクリックすれば動きます).

まとめ

  • Vue.jsはCDN + Import Mapで導入できる — npm不要

  • import { createApp } from 'vue' — ブラウザネイティブのESMで読み込む

  • 既存のHTMLを <div id="app"> で囲んでマウントするだけ

  • 見た目は何も変わらない — これがProgressive

  • setup() の中でref() を使ってリアクティブなデータを定義する

  • ファイルは依然としてindex.html一枚だけ