
【フロントエンドフレームワーク基礎】part1:フロントエンド技術の基礎知識
みなさんこんにちは、@ultaroです!
今回は、フロントエンドフレームワークの基礎シリーズのpart1として「フロントエンド技術の基礎知識」を紹介します!
1. はじめに
1-1. フロントエンドフレームワークとは
フロントエンドフレームワークは、ウェブアプリケーションのユーザーインターフェース(UI)を構築するためのツールセットです。ウェブアプリケーションの評価はUI/UXにあるといっても過言ではありません。フロントエンドフレームワークは、高いUI/UXを実現するために、HTML、CSS、JavaScriptなどを効果的に使い、ユーザーにとって使いやすく、開発者にとって保守しやすいコードを書くことを可能にします。
1-2. フロントエンドフレームワークのコアコンセプト
フロントエンドフレームワークのコアコンセプトとして、以下のものがあげられます。
💠コンポーネントベースのアーキテクチャ
💠データバインディング
💠クライアントサイドルーティング
💠状態管理
これらのコアコンセプトについて詳しく見ていきましょう!
2. コンポーネントベースのアーキテクチャ
2-1. コンポーネントとは
コンポーネントは、ユーザーインターフェース(UI)の特定の部分を構成する再利用可能な独立したコードの単位です。これには、ボタン、入力フォーム、ナビゲーションバー、モーダルウィンドウなどが含まれます。下の図の例ではHeader、Main、Article、Aside、Itemがそれぞれコンポーネント化されています。

(Vue.js公式サイトより引用)
各コンポーネントは、HTML、CSS、JavaScriptを組み合わせて、一つの自己完結型の機能を提供します。例えば、ボタンコンポーネントは、その見た目(スタイル)と動作(クリックイベント)を定義し、どこでも同じボタンを再利用できるようにします。
2-2. コンポーネントベースでの開発のメリット
コンポーネントベースの開発により開発プロセスがモジュール化され、各コンポーネントが独立して開発、テスト、および保守されます。コンポーネントベースの開発をすることで得られるメリットは以下のものがあります。
✅再利用性
一度作成したコンポーネントは、他のプロジェクトやアプリケーション内で再利用できます。これにより、同じコンポーネントを作成する必要がないので、開発の効率が向上します。
✅UIの一貫性の確保
同じコンポーネントを使いまわすことで、同じデザインと挙動を複数の画面で実現できます。これにより画面ごとのUIのバラツキをおさえることができます。
✅保守性の向上
各コンポーネントが独立しているため、特定の部分の修正や更新が容易です。問題が発生した場合、そのコンポーネントだけを修正すればよいので、全体のアプリケーションに影響を与えるリスクが低減されます。
✅コードの可読性と管理
コードが小さな部分に分割されるため、理解しやすくなり、コードベース全体の管理が容易になります。
✅チーム開発の効率化
開発チームのメンバーが異なるコンポーネントに分かれて作業することができるため、作業の並行性が向上し、プロジェクトの進行がスムーズになります。
2-3. コンポーネント実装の例
以下はVueで作成したコンポーネント実装の一例です。コンポーネントを次のように定義します。「UserCard」の実装例です。
<template>
<div class="user-card">
<img :src="avatar" alt="User Avatar" class="avatar" />
<h2>{{ name }}</h2>
<p>{{ title }}</p>
</div>
</template>
<script>
export default {
name: 'UserCard',
props: {
name: {
type: String,
required: true
},
title: {
type: String,
required: true
},
avatar: {
type: String,
required: true
}
}
}
</script>
<style scoped>
.user-card {
border: 1px solid #ccc;
border-radius: 8px;
padding: 16px;
margin: 16px auto;
max-width: 300px;
text-align: center;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.avatar {
border-radius: 50%;
width: 100px;
height: 100px;
margin-bottom: 16px;
}
</style>
このコンポーネントはUIのロジックとスタイルが一つの場所にまとまっており、UIに変更が必要になった際、たとえば 「.user-card」クラスを修正するだけで全ての「UserCard」インスタンスに反映されます。これにより複数個所で個別に修正する必要がなくなり、UIの一貫性が担保されるとともに保守性が向上します。
以下は3つのUserCardを表示させる例です。
<template>
<div id="app">
<h1>ユーザーリスト</h1>
<UserCard
name="John Doe"
title="Software Engineer"
avatar="https://via.placeholder.com/150"
/>
<UserCard
name="Jane Smith"
title="Product Manager"
avatar="https://via.placeholder.com/150"
/>
<UserCard
name="Emily Johnson"
title="UX Designer"
avatar="https://via.placeholder.com/150"
/>
</div>
</template>
上記の例では、「UserCard」がコンポーネント化されていることにより再利用可能なコンポーネントとなり、前述のメリットが得られます。
3. データバインディング
3-1. データバインディングとは
データバインディングとは、ユーザーインターフェース(UI)とフロントエンドアプリケーションのデータの状態をリンクさせる仕組みです。これにより、アプリが管理するデータが変更となった場合にUIのデータも自動的に変更されます。ここで、Reactでのデータバインディングの例を見てみましょう!
const [text, setText] = useState('');
const handleChange = (event) => {
setText(event.target.value);
};
return (
<div>
<input type="text" value={text} onChange={handleChange} />
<p>{text}</p>
</div>
);
ソースコードを紐解いてみます。
const [text, setText] = useState('');
この部分では、ReactのuseStateフックを使ってtextという状態変数と、それを更新するためのsetTextという関数を定義しています。このtextがUIとデータをリンクさせる役割を果たします。
<div>
<input type="text" value={text} onChange={handleChange} />
<p>{text}</p>
</div>
ここで実際にデータバインディングが行われています。先ほど紹介したtextという状態変数の値がinputタグのvalueやpタグで囲われた部分に渡され、inputやpタグの値として表示されます。
const handleChange = (event) => {
setText(event.target.value);
};
また、onChangeイベントを使って、ユーザーがテキストフィールドに入力するたびにhandleChange関数が呼ばれ、その結果textの値が更新されます。これにより、UIと状態がリンクし、ユーザー入力が即座に反映されます。
3-2. 単方向バインディングと双方向バインディングの違い
データバインディングには「単方向バインディング」と「双方向バインディング」の2種類存在します。
✅単方向バインディング
単方向バインディングは、データが一方向にのみ流れるバインディング方法です。つまり、JavaScriptのデータモデルからビュー(HTML)にデータが渡されるだけで、ビューからデータモデルへの逆の流れはありません。これにより、データの表示や状態の変更はJavaScriptのインスタンス内で行われ、ビューはその状態を単に表示するだけです。

以下のReactの例では、messageのデータはtemplate内の<input>タグに表示されますが、ユーザがこの<input>タグを通じてmessageの値を変更することはできません。
const [message, setMessage] = useState('Hello React!');
return (
<div id="app">
<input type="text" value={message} />
<p>{text}</p>
</div>
);
双方向バインディングと比較して単方向バインディングの良いところは、データフローとビューの更新が明確に分離されていることです。データはデータモデルからビューへの流れしかなく、ビューはデータモデルから受け取ったデータを表示するだけと役割が分離されています。
これにより、デバックや保守が容易になりコードの予測可能性が高くなります。単方向バインディングでビューからデータモデルへの逆のデータフローを実現する場合はイベントを手動で作成します(上記概要図の点線矢印部分)。この場合もデータフローとビューの更新の分離ができているため保守性は維持されます。
✅双方向バインディング
双方向バインディングは、データが双方向に流れるバインディング方法です。JavaScriptのインスタンスのデータとビューの間で相互にデータが更新されます。ビュー(通常はフォーム要素)でデータを変更すると、その変更がJavaScriptのインスタンス内のデータにも即座に反映されます。そして逆に、JavaScriptのインスタンスのデータを変更すると、その変更がビュー内の要素にも反映されます。

以下のVueの例では、<input>要素に入力された値がmessageデータに反映され、その結果が即座に<p>タグに表示されます。逆に、JavaScriptのインスタンス内のmessageデータが変更されると、その変更が<input><p>要素にも反映されます。
<div id="app">
<input v-model="message">
<p>{{ message }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
単方向バインディングと異なる点は、ビューからデータモデル変更の際にイベントを手動で書く必要がないところです。v-modelを使用して双方向バインディングを実現することで、コードがシンプルになり開発効率も向上します。
4. クライアントサイドルーティング
4-1. クライアントサイドルーティングとは
クライアントサイドルーティングは、Webアプリケーションの異なるページやビューへのナビゲーションを、ページ全体のリロードなしで実現する技術です。これにより、コンテンツが切り替わる際のストレスを軽減し、ユーザ体験を向上できます。
クライアントサイドルーティングはSPAの実現に不可欠な技術です。SPAは、単一のHTMLページで構成されるモダンなWebアプリケーションのアーキテクチャです。初回ロード時にすべての必要なリソース(HTML、CSS、JavaScriptなど)を取得し、その後のページ遷移は必要な部分だけ再レンダリングし、クライアントサイドで処理されます。

5. 状態管理
5-1.状態管理とは
まず、「状態」とは、アプリケーション内で一時的に保持されるデータのことです。たとえば、ECサイトのカートに商品を追加すると、そのカートの中身が「状態」にあたります。この「状態」はページを移動しても保持され、ユーザーの操作に応じて変化します。
「状態管理」とは、「状態」を一貫して保持し、必要に応じて更新する仕組みのことです。フロントエンドフレームワークでは、コンポーネント間で状態を共有する必要があるため、複雑なアプリケーションでは状態管理が重要になります。代表的な状態管理ライブラリには、ReduxやVuexがあります。これらのライブラリはアプリの状態を集中管理し、各コンポーネントでの処理を効率的にする役割を果たします。
5-2.状態管理の重要性
状態管理を行わない場合に、一時データを保持するためには次の二つの方法が考えられます。
🔷データベースに一時データを保存する
そもそもこの方法では「一時データ」ではなくなってしまいますが…「データを保持しUIに表示する」という内容は実現できます。しかし随時データベースとデータをやり取りすると、不要な負荷がかかったり、UIへのデータの即時反映ができなかったりするため、ユーザの操作感はかなり落ちるでしょう。
🔷submitや画面遷移を行うたびに、一時データを保持し続ける
この方法では非常に複雑な実装をしなければならず、複数の画面やコンポーネント間でデータの整合性を保つのが難しくなります。異なる箇所で状態が異なる形に更新されたり、古い状態を引き継いでしまう可能性があり、ユーザに対して不整合なデータが表示されることがあります。
このように、紹介した二つの方法には大きなデメリットが存在します。状態管理があるからこそ、そのようなデメリットがなくなり、素晴らしいユーザ体験を提供できたり保守性の高いコードが書けるというわけです!
6. まとめ
本記事では、フロントエンドフレームワークの基礎について説明しました。フロントエンドフレームワークは、効率的なウェブアプリケーションの開発を支える重要なツールセットであり、UIの構築やデータ管理など、さまざまな開発課題を解決するための機能が備わっています。
フロントエンドフレームワークの中核にあるコンポーネントベースのアーキテクチャは、再利用性と保守性の向上をもたらし、開発の効率化に貢献します。また、データバインディングやクライアントサイドルーティング、状態管理といった機能も、複雑なアプリケーションの開発をシンプルかつ効果的に進めるための支援を行います。
これらの技術と機能を正しく理解し活用することで、開発者はより高品質なアプリケーションを効率的に構築できるようになります。ぜひフロントエンドフレームワークを活用していきましょう!