はじめてのVue.js【人気のJavaScriptフレームワークを解説】
はじめに
人気のJavaScriptフレームワーク「Vue.js」の特徴と、インストール方法、そして基本的な機能について学習しましょう。
Vue.jsとは
https://jp.vuejs.org/index.html
Vue.jsはJavaScriptのUIフレームワークです。
Vueは、ユーザーインターフェイスを構築するためのプログレッシブフレームワークです。他のモノリシックなフレームワークとは異なり、Vue は少しずつ適用していけるように設計されています。
はじめに | Vue.js
Vue.jsは段階的、部分的に導入しやすいことが特徴です。その一方で、大規模な開発においても利用できる使い勝手の良いUIフレームワークの1つです。このような特徴からjQueryなどで構築された古いシステムをモダンな実装へ切り替える目的でも使われています。
Reactとの比較
類似するUIフレームワークとしてReactが挙げられます。コンポーネント単位でUIを構築していく点はReactと共通しています。
UIの構築においては、Reactに比べるとHTML側で組み立てるイメージです。ReactではfilterやmapといったJavaScriptのメソッドを主に利用してUIを構築します。一方で、Vue.jsではディレクティブと呼ばれるHTMLの属性のようなものを利用します。そのため、比較的HTMLを組み立てるのに近い感覚でUIを構築してきます。
またVue.jsはReactと比べるとTypeScriptとの相性が良くないと言われています。TypeScriptは、型チェックによりシステムの品質を向上できる一方で、導入の敷居の高いと言われています。一般的に、ReactはTypeScriptを前提とした利用が多く、Vue.jsはJavaScriptで使用されているのが多い印象です。
Reactの解説動画もありますので併せてご覧ください。
インストール方法
Vueの導入方法です。主な導入方法は次のとおりです。
- CDNから
<script>タグで読み込む - npmやyarnといったパッケージマネージャを用いる
- 公式CLIを用いてセットアップする
詳しくは公式のインストール手順を参考にしてください。
ここでは最も簡単なCDNを用いた方法で進めます。HTMLファイルの<head>タグ内に次の1行を追加します。
<script src="https://unpkg.com/vue@next"></script>
URLの@nextは最新版を意味しており、Vue3がインストールされます。
宣言的レンダリング
dataメソッド
const App = {
data() {
return {
counter: 5,
}
}
}
Vue.createApp(App).mount('#app')
<div id="app">
Counter: {{ counter }}
</div>
Appという変数に代入されているのはdataというメソッドをもつオブジェクトです。dataメソッドは、Vueにおいてデータを扱うメソッドです。Vue.createAppメソッドにこのオブジェクトを渡すことで、画面にデータを反映させることができるようになります。そしてmountメソッドで#appと記述することで、idがappの要素をVueアプリケーションのマウント先に指定しています。
HTML内の{{ counter }}という波括弧2つで囲む記法は、データを扱うためのVueの記法です。扱うデータというのは、Appオブジェクトの中のdataメソッドで返しているデータです。よってcounterの値が反映され、0が表示されます。
mountedメソッド
次に、1秒ごとにcounterの値が増える例を見てみましょう。
const App = {
data() {
return {
counter: 0,
}
}
+ mounted() {
+ setInterval(() => {
+ this.counter++;
+ }, 1000);
+ }
}
mountedメソッドはVueのライフサイクルの1つで、マウントされた時に呼び出される処理を記述します。setIntervalを用いて1000ミリ秒ごとにthis.counterをインクリメントします。this.counterと記述することで、dataメソッド内で定義したcounterを参照しています。
このように、Vue.jsでは宣言的レンダリングを用いることで簡単にDOM操作を実装できます。
属性バインディング (v-bind)
先ほどはHTMLタグ内に値を反映させましたが、属性に反映させるにはv-bindを使用します。
<span v-bind:title="message">
Hover your mouse over me for a few seconds to see my dynamically bound title!
</span>
const App = {
data() {
return {
message: 'You loaded this page on ' + new Date().toLocaleString()
}
}
}
この例のdataメソッドは、messageというプロパティをもつオブジェクトを返しています。vbind:titleによってspan要素のtitle属性にmessageの値を反映させます。
ユーザー入力の制御
イベントを扱う (v-on)
<p>{{ message }}</p>
<button v-on:click="reverseMessage">Reverse Message</button>
const App = {
data() {
return {
message: 'Hello Vue.js!'
}
},
methods: {
reverseMessage() {
this.message = this.message.split('').reverse().join('')
}
}
}
v-on:clickにはクリック時に呼び出すメソッド名を指定します。(今回はreverseMessageを指定)App内には、methodsというオブジェクトの中にメソッドを定義します。今回定義したreverseMessageというメソッドはmessageの文字列を反転させます。
双方向に反映させる (v-model)
<p>{{ message }}</p>
<input v-model="message" />
const App = {
data() {
return {
message: 'Hello Vue!'
}
}
}
input要素に入力をするとJavaScriptのmessageの値を書き換えることができ、{{ message }}の部分へ即座に反映されます。このような相互に反映される仕組みを双方向バインディングと言い、Vueではv-modelを使いシンプルに記述できます。
条件分岐とループ
条件分岐 (v-if)
表示条件を定めるにはv-ifを使用します。
<span v-if="seen">Now you see me</span>
const App = {
data() {
return {
seen: true
}
}
}
seenの値の真偽によってspan要素の表示/非表示を切り替えることができます。
ループ (v-for)
ループを実装するにはv-forを用います。
<ol>
<li v-for="todo in todos">
{{ todo.text }}
</li>
</ol>
const App = {
data() {
return {
todos: [
{ text: 'Learn JavaScript' },
{ text: 'Learn Vue' },
{ text: 'Build something awesome' }
]
}
}
}
JavaScript側ではtextというオブジェクトをもつ配列todosを返します。v-for="todo in todos"は、todosの要素1つ1つをtodoという名前で取り出すことを意味します。そして{{ todo.text }}によって要素todoのから文字列を取り出しています。
コンポーネントによる構成
コンポーネントによりUIを分割できることはVue.jsの特徴の1つです。Todoリストの項目を1つだけ表示するTodoItemコンポーネントを次のように定義します。
const TodoItem = {
props: ['todo'],
template: `<li>{{ todo.text }}</li>`
}
templateはVueの構文で書かれたHTMLタグを文字列で指定しています。この中でtodo.textという値を参照しています。このコンポーネントはtodoを受け取る必要があるので、propsの配列には"todo"と指定します。
次にTodoItemコンポーネントをApp`で利用します。
const App = {
data() {
return {
groceryList: [
{ id: 0, text: 'Vegetables' },
{ id: 1, text: 'Cheese' },
{ id: 2, text: 'Whatever else humans are supposed to eat' }
]
}
},
components: {
TodoItem
}
}
新しい部分はcomponentsにTodoItemを指定している点です。これによって、App内でTodoItemが使えるようになります。
<div id="app">
<ol>
<todo-item
v-for="item in groceryList"
v-bind:todo="item"
v-bind:key="item.id"
></todo-item>
</ol>
</div>
v-forでgroceryListから1つずつitemに項目を取り出します。このitemを、v-bindによってTodoItemのpropsで指定したtodoに渡します。
もう1つ特徴的なのが、v-bind:keyを指定している点です。ユニークなキーを指定することでループのパフォーマンスを向上させることができるので、item.idを渡しています。
今回のコンポーネントはli要素のみで比較的シンプルなコンポーネントでしたが、より複雑な構造を行う場合は適切な粒度でコンポーネント分割することにより見通しの良いコードを実現できます。
また、SPA(Single Page Application)を構築するような際には、JavaScriptのモジュール機能によりファイル分割するニーズが出てきます。こうした際にコンポーネントの分割が役に立ちます。
まとめ
今回はVue.jsの基本機能を紹介しました。Vue.jsでできることはまだ多くありますが、今回紹介した範囲でJavaScriptやjQueryで作成していた処理をモダンな実装でリファクタリングも可能になります。Vueの公式サイトもチェックし、ぜひ開発に取り入れてみてください。