frontendBaby

公開日

- 17 分で読めます

第13話 「博士からの卒業証書」(最終話)


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

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


登場人物紹介

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

第13話🦝「博士からの卒業証書」(最終話)

その日、研究所の空気はいつもと少し違っていた。博士は腕を組み、厳しい顔でモニターを見つめている。ポン吉はゴクリと息をのみ、緊張した面持ちで自分の席に座っていた。

博士: 「ポン吉よ。今日が最終試験じゃ。これまでワシが教えたこと、そのすべてをこの場で証明してもらう。」

ポン吉: 「は、はいっ!ポン…!」

声が少し裏返ってしまった。無理もない。目の前のモニターには、空っぽのファイルが一つだけ開かれている。今日の課題は、ゼロから一つのアプリケーションを作り上げることなのだ。

博士: 「お題は、『簡易ToDoリスト』じゃ。やるべきことを追加でき、完了したら打ち消し線で消せる。ただ、それだけじゃ。しかし、条件がある。」

博士は一本の指を立てた。

博士: 「第一に、createAppからComponentの設計まで、すべて型安全であること。TypeScriptの力を最大限に活かすのじゃ。」

博士は二本目の指を立てた。

博士: 「第二に、コンポーネントは適切に分割すること。入力フォーム、リスト表示、リストの各項目。それぞれが独立した、再利用可能な部品となるように設計するんじゃ。」

そして、三本目の指を立てた。

博士: 「最後に、ワシは一切、手も口も出さん。質問も許さん。自分の力だけで、この課題を乗り越えてみせるのじゃ。…始め!」

その言葉を合図に、ポン吉はキーボードに手を置いた。カタカタ…と、小さな音だけが研究所に響く。

createApp…まずはアプリの器を作るんだ…)

ポン吉は、第一話で教わったことを思い出す。main.tsファイルを作り、アプリケーションのエントリーポイントを記述した。

(次はコンポーネント設計だ…博士は分割しろって言ってたな…)

ポン吉は紙に、コンポーネントの親子関係図を描き始めた。一番上にApp.vue。その下に、新しいToDoを追加するTodoForm.vueと、ToDoの一覧を表示するTodoList.vue。さらにその下に、個々のToDo項目であるTodoItem.vue

ポン吉: 「よし…!propsemitsの流れはこうだ…!」

App.vueがToDoのリスト全体を状態として持ち、TodoFormが新しいToDoを追加するイベントをemitする。App.vueはそのイベントを受け取ってリストを更新し、更新されたリストをpropsとしてTodoListに渡す。TodoListはリストをループしてTodoItemに個別のToDoを渡し、TodoItemは完了イベントをemitする…。

頭の中で、データの流れが明確にイメージできた。これまでの博士との対話が、血肉となっている証拠だった。

カタカタカタ…!キーボードの音が力強くなる。

まずはTodoItem.vueからだ。一番小さな部品から作るのが定石。

// TodoItem.vue
<script setup lang="ts">
interface Todo {
  id: number;
  text: string;
  completed: boolean;
}

const props = defineProps<{ todo: Todo }>()
const emit = defineEmits<{ (e: 'toggle-complete', id: number): void }>()
</script>

<template>
  <li :class="{ completed: props.todo.completed }" @click="emit('toggle-complete', props.todo.id)">
    {{ props.todo.text }}
  </li>
</template>

<style scoped>
.completed { text-decoration: line-through; }
li { cursor: pointer; }
</style>

(よし!definePropsdefineEmitsで型を定義…!これで親との契約は完璧だ!)

次にTodoList.vue、そしてTodoForm.vue。ポン吉は夢中でコードを書いていく。途中、propsの型を間違えて、エディタに赤い波線が表示された。

ポン吉: 「あっ…!」

以前ならパニックになっていたかもしれない。だが、今のポン吉は違った。TypeScriptからのエラーメッセージをじっと読む。

(「型 ‘number’ を型 ‘string’ に割り当てることはできません。」…なるほど、渡すデータの型が違うのか。)

冷静に間違いを修正する。博士が言っていた「エラーは友達」という意味が、今ならよく分かる。TypeScriptは、ポン吉が道を踏み外さないように、常に隣で声をかけ続けてくれていた。

そして、すべての部品が組み上がり、最後のApp.vueを完成させた。

// App.vue
<script setup lang="ts">
import { ref } from 'vue'
import TodoForm from './TodoForm.vue'
import TodoList from './TodoList.vue'

interface Todo {
  id: number;
  text: string;
  completed: boolean;
}

const todos = ref<Todo[]>([])
let nextId = 0

function addTodo(text: string) {
  todos.value.push({ id: nextId++, text, completed: false })
}

function toggleComplete(id: number) {
  const todo = todos.value.find(t => t.id === id)
  if (todo) {
    todo.completed = !todo.completed
  }
}
</script>

<template>
  <h1>ポン吉のToDoリスト</h1>
  <TodoForm @add-todo="addTodo" />
  <TodoList :todos="todos" @toggle-complete="toggleComplete" />
</template>

すべてのファイルを保存し、ポン吉は震える手でブラウザをリロードした。画面には「ポン吉のToDoリスト」という見出しと、入力フォームが表示されている。

フォームに「博士にお礼を言う」と入力し、追加ボタンを押す。リストに項目が追加された。その項目をクリックすると、打ち消し線が引かれる。

ポン吉: 「で、できた…!動いた…!」

ポン吉の目に、じわっと涙が滲んだ。自分の力 で、学んだ知識だけを頼りに、一つのアプリケーションをゼロから作り上げたのだ。その達成感は、今まで感じたことのない、大きな喜びだった。

その時、ずっと沈黙を守っていた博士が、ゆっくりと拍手をした。

パチ…パチ…パチ…

博士: 「見事じゃ、ポン吉。完璧な出来栄えじゃ。」

博士の目も、少し潤んでいるように見えた。

博士: 「君はもう、ただの物知りな子タヌキではない。問題に立ち向かい、設計を考え、コードを書き、自力でバグを修正できる…立派なフロントエンドエンジニアの卵じゃ。」

博士は机の引き出しから、一枚の羊皮紙を取り出した。そこには、こう書かれていた。

----------------------------------------

       フロントエンド博士認定

           卒業証書

 ポン吉殿

あなたはVue.jsとTypeScriptの
探求の旅を立派に成し遂げました
その好奇心と探求心を称え
ここに卒業を認定します

これからも学び続け
素晴らしいアプリケーションを
世界に生み出してくれることを
期待しています

フロントエンド博士より

----------------------------------------

ポン吉: 「博士…!」

ポン吉は、卒業証書を受け取ると、こらえきれずにワッと泣き出した。悔し涙ではない。嬉しくて、誇らしくて、そして少し寂しい、温かい涙だった。

博士: 「泣くでない、ポン吉。卒業は終わりではない、新しい始まりじゃ。君の前には、広大なフロントエンドの海が広がっておる。React、Angular、Svelte…まだまだ探検すべき大陸はたくさんある。今日のこの成功を自信に変えて、これからも前進し続けるのじゃ。」

ポン吉: 「はい…!はいっ…!博士、本当に、本当にありがとうございました!ポン!ポン!」

ポン吉は涙を拭うと、満面の笑みで何度も何度も頭を下げた。尻尾も、ちぎれんばかりに振られている。

森の奥の不思議な研究所での出会いから始まった、子タヌキの冒険。彼は、createAppの謎から始まり、Componentの型、そしてTypeScriptの魔法まで、多くのことを学んだ。しかし、彼が手に入れた一番大切なものは、知識そのものではなく、「自ら学び、考え、作り上げる力」だったのかもしれない。

夕日に照らされながら、卒業証書を大事に抱えて研究所を去るポン吉の後ろ姿を、博士はいつまでも見送っていた。

博士: 「行け、ポン吉。君なら、きっと素晴らしいエンジニアになれるじゃろう…。」

ポン吉の冒険は、まだ始まったばかりだ。


🌟 物語のまとめ

  • createApp は、アプリケーションの器を作る最初の魔法。
  • h関数VNode は、Vueの高速な描画を支える仮想DOMの仕組みの核心。
  • TypeScript型定義 は、コードを安全で頑丈にするための、頼もしい味方。
  • Component は、Props, Emits, Slotsなどの仕組みを通じて、再利用可能で柔軟な部品作りを可能にする。
  • Composition API<script setup> は、ロジックを分かりやすく整理し、開発を加速させる。
  • そして何より、エラーを恐れず、自ら考え、一歩ずつ学び続けること が、最高のエンジニアへの道!

👨‍🏫 博士からの卒業メッセージ

13話にわたる長い物語を、最後まで読んでくださった皆さん、本当にありがとうじゃ。

振り返ってみると、第1話でポン吉が研究所にやってきた時、彼はcreateAppすら知らない、本当に素朴な子タヌキじゃった。それが今では、型安全なVueアプリケーションを一人で作り上げるまでに成長した。この成長こそが、真の学習というものじゃ。

ポン吉が手に入れたものは、単なる知識ではない。**「分からないことがあっても、自分で調べ、考え、試行錯誤する力」**じゃ。これこそが、技術が次々と変わっていくこの業界で、一生涯役に立つ宝物なんじゃよ。

📚 皆さんの学習の旅路

この物語を読んでくださった皆さんも、きっとポン吉と同じような学習の旅路を歩まれておることじゃろう。

  • 最初は「なんだこれは?」と戸惑い
  • 少しずつ「あ、そういうことか!」と理解し
  • 時には挫折しそうになりながらも
  • 最後には「自分でもできた!」という達成感を味わう

この繰り返しが、皆さんを確実に成長させてくれる。エラーに出会うたび、新しい概念に出会うたび、「これはポン吉も通った道じゃな」と思い出してもらえれば嬉しいのう。

🚀 新しいスタートラインに立つ皆さんへ

この連載を最後まで読んだ皆さんは、もはや初心者ではない。Vue.jsとTypeScriptの基礎をしっかりと身につけた、フロントエンドエンジニアの卵じゃ。

これから皆さんの前には、広大な可能性が広がっておる:

  • より複雑なアプリケーションの構築
  • チームでの開発体験
  • ユーザーに喜ばれるサービスの創造
  • そして、今度は皆さんが他の誰かに教える側になること

💌 博士からの最後のお願い

最後に、一つだけお願いがある。

もし、この先の学習で迷ったり、困ったりすることがあっても、決して諦めないでほしい。ポン吉がそうだったように、「分からない」は「これから分かるようになる」の始まりなんじゃ。

そして、いつか皆さんが誰かのメンターになった時、この連載で感じた「学ぶ楽しさ」を、次の世代にも伝えてもらえれば、これ以上の喜びはないのう。

皆さんの成長と成功を、心から祈っておるぞ。


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