frontendBaby

公開日

- 11 分で読めます

第4話 「createAppが返すもの」


どうしてもVue.jsが分からないので森の博士の研究所に押しかけてみたら、人生が激変した子タヌキの話

この物語は、フロントエンド技術を楽しく学ぶことを目的に、生成AIを活用して執筆されています。 技術的な情報の正確性には細心の注意を払っていますが、その内容がすべて真実であることを保証するものではありません。 あくまで学習の補助ツールとして、肩の力を抜いてお楽しみください。


登場人物紹介

  • フロントエンド博士: 森の奥の研究所に住む、フロントエンドのことなら何でも知っている物知り博士。ポン吉の素朴な疑問にいつも優しく(そして面白おかしく)答えてくれる。
  • ポン吉: 好奇心旺盛な子タヌキ。将来の夢はフロントエンドエンジニア。最近Vue.jsを学び始めたが、その奥深さに興味津々。新しい知識をゲットすると、思わず「ポン!」と飛び跳ねる特技あり。

第4話🦝「createAppが返すもの」

今日も元気に研究所にやってきたポン吉。博士と一緒にこれまでのコードを見返していた時、ふとあることに気づいた。

ポン吉: 「博士、僕たちはずっと createApp(App).mount('#app') って一行で書いてきましたけど…」

ポン吉はモニターのコードを指差した。

ポン吉: 「この .mount() の前にある createApp(App) って、実行された後、一体『何』になっているんですか?そのまま .mount() に繋がっているから、何かが返ってきているんですよね?」

博士はポン吉の鋭い観察力に感心し、にっこりと笑った。

博士: 「素晴らしい質問じゃ、ポン吉!その通り!createApp 関数は、実行されるとあるものを返してくる。それを知ることが、Vueアプリケーションをより深く理解する鍵なんじゃよ。」

博士: 「それはな、『アプリケーションインスタンス』と呼ばれるものなんじゃ。百聞は一見にしかずじゃ。こうしてみよう。」

博士はコードを少し書き換えた。

import { createApp, h } from 'vue'

const App = {
  render() {
    return h('h1', 'アプリケーションインスタンスの正体!')
  }
}

// createAppが返すものを、一度変数appに入れてみる
const app = createApp(App)
console.log(app) // 中身をコンソールで見てみよう

app.mount('#app')

ポン吉: 「あ!一行だったのが二行になった!appっていう変数に入れたんですね。」

博士: 「そうじゃ。そして、ブラウザの開発者ツールでコンソールを見てごらん。」

ポン吉がコンソールを覗き込むと、そこには Object と表示され、中には component, directive, mount, unmount, use, provide といった、たくさんのプロパティが詰まっていた。

ポン吉: 「うわー!ただの関数じゃなくて、たくさんの機能が詰まったオブジェクトが返ってきていたんですね!mount もこの中の一つだったんだ!」

博士: 「その通り!この app インスタンスは、君が作るアプリケーション全体の『司令塔』のようなものじゃ。例えば、app.component() を使えば、どのコンポーネントからも呼び出せる『グローバルコンポーネント』を登録できる。app.use() を使えば、便利なプラグインを追加して、アプリケーション全体の機能を拡張することもできるんじゃよ。」

ポン吉: 「司令塔…!なるほど!だから、アプリケーションをマウントする前に、色々な設定をこの app にしておくことができるんですね!」

博士は満足そうに頷いた。

博士: 「そういうことじゃ。createApp は、単にアプリケーションの『器』を作るだけでなく、その器を管理し、味付けするための強力な『司令塔』を生み出す魔法でもあったんじゃな。」

ポン吉は、いつも何気なく書いていた一行のコードの裏に、こんなにも広大な世界が広がっていたことに驚き、興奮を隠せない様子だった。

ポン吉: 「博士、ありがとうございます!createApp の本当の姿が分かりました!ポン!」

博士: 「うむ。では次回は、コンポーネント同士がどうやってお話をするのか、その基本となる『Props』について学んでいこうかの。」

ポン吉: 「はい!よろしくお願いします!」

アプリケーションの司令塔を手に入れたポン吉。彼の冒険は、まだ始まったばかりだ。


🌟 今日のまとめ

  • createApp(App) は、ただの関数呼び出しではなく、アプリケーションインスタンスという特別なオブジェクトを返す。
  • このインスタンスは、アプリケーション全体の「司令塔」の役割を持つ。
  • app.component()app.use() のようなメソッドを使って、アプリ全体に関わる設定や機能拡張ができる。
  • .mount() は、この司令塔が持つ数ある機能の一つに過ぎない。

次回予告 「コンポーネントに命を吹き込む『Props』」

コンポーネントは一人では生きていけない?親子コンポーネントがデータをやり取りするための魔法「Props」の謎に迫ります!

👨‍🏫 博士からの補足

ポン吉は createApp が返す「アプリケーションインスタンス」の便利さに気づき始めたようじゃな。app.use() でプラグインを追加したり、app.component() でグローバルなコンポーネントを登録したり…。これらは全て、ブラウザ(DOM)の世界でリッチなアプリケーションを作るための機能じゃ。

しかし、もしVueの活躍の場がブラウザだけに限られないとしたら、どうじゃろう?

第一話の補足で、わしは createApp@vue/runtime-dom というパッケージから来ていると話したのを覚えておるかな? 実は、Vueの心臓部にはもう一つ、さらに重要なパッケージが存在する。それが @vue/runtime-core なんじゃ。

@vue/runtime-dom が「ブラウザの世界でVueを動かすための機能」だとすれば、@vue/runtime-core は、特定の環境に依存しない、Vueの最も純粋な機能(リアクティビティシステムや仮想DOMなど)だけを詰め込んだ、いわば「Vueの魂」のようなパッケージなんじゃよ。

そして、この @vue/runtime-core の中には、createRenderer という、究極の魔法とも言える関数が隠されておる。

この createRenderer は、Vueのコンポーネントツリーを、実際に何らかの形で描画するための「描画エンジン」そのものを作り出す関数なんじゃ。 createApp は、実はこの createRenderer を使って、あらかじめ「ブラウザのDOMを描画するためのエンジン」を内蔵した状態で我々に提供されている、便利なショートカットに過ぎんのじゃよ。

もし、我々が createRenderer を直接使えば、どうなるか? 独自の描画ロジックを定義することで、ブラウザの外の世界でVueのコンポーネントを動かすことすら可能になるんじゃ。

実際に、世の中の賢い開発者たちはこの仕組みを利用して、こんなことを実現しておる:

  • 🎨 Canvas に描画する Vue コンポーネント - DOM要素ではなく、Canvas上に図形やグラフィックスを描画
  • 📦 CLI ツールで Vue を使って UI を構築 - ターミナル上で動作するインタラクティブなコマンドラインツール
  • 📱 ネイティブアプリや WebGL に Vue を使いたい - モバイルアプリや3Dグラフィックスの世界でVueコンポーネントを活用
  • 🧪 Vue のレンダリング挙動をテスト・実験したい - テスト環境で仮想的な描画を行い、Vueの動作を検証

つまり、ポン吉が今学んでいるVueのコンポーネントの書き方は、Webページを作るためだけの技術ではないんじゃ。その気になれば、あらゆる場所のUIを構築できる、普遍的な力を持っているということじゃな。

まあ、今はまだ壮大すぎる話かもしれん。じゃが、君が学んでいる知識の先には、ブラウザの枠を越えた、無限の可能性が広がっているということ。それを頭の片隅に置いておいてくれると、わしは嬉しいぞい。


第4話 おわり