アプリを作ろう(6):JavaScriptの基本
前回のVuetifyの説明の最後にv-date-pickerを紹介しましたが、そのサンプルをもう一度見てみましょう。
青い部分に本来なら選択した日付が表示されるはずですが、表示されていません。これは前回省略したv-modelが指定されていないためです。
v-modelは簡単にいうと日付情報を格納しておくための変数の指定場所になります。では変数はどのように指定すればよいのか、ということをこの記事で説明します。
Webページの構造
そもそもWebページはどのように作られているのでしょうか。Webページは以下の3つの要素から作られています。
HTML
<h1>や<div>などのタグを使って記述するのがHTMLです。HTMLはWebページの見た目を決めると思われがちですが、実はHTMLは構造を決める役割になります。
CSS
HTMLに代わってWebページの見た目を決めるのがCSSになります。例えば背景色を変える場合はbackground-colorを変更します。
JavaScript
最後にWebページの動的な機能を提供するのがJavaScriptです。クリックしたときに情報が表示される、ページが変わる、色が変わるといった部分はJavaScriptで担います。
このような3つの分類で理解することが大切ですが、実際にはHTMLである程度見た目を変えられますし、動的な動きも可能です。あくまで原則ですが、単純化して理解しましょう。
VueにおけるHTML/JavaScript/CSS
Vueではこの3要素を簡潔に書き分けできます。下記のようにtemplate, script, styleの3つのタグの中に記述するのです。
<template>
<!-- HTML -->
</template>
<script>
// JavaScript
</script>
<style>
/* CSS */
</style>
このタグの中にそれぞれの中身を記述していきます。前回までのサンプルではtemplateのみを記述してscriptとstyleを省略していました。
ではv-date-pickerの日付をクリックしたときの挙動に関する部分はどこに記述すればよいでしょうか?当然、JavaScriptの部分になります。
VueにおけるJavaScript
以下にJavaScriptについて解説していきますが、最小限しか行いません。今はJavaScriptを直接書くことがかなり減ってきていて、TypeScriptなどの別の言語で書かれたプログラムをJavaScriptに変換する方法が主流となっています。今後、TypeScriptの解説を加えますが、その前段としての解説だと思ってください。
いきなり正解を出しましょう。v-date-pickerのソースを下記のように書き換えれば日付をクリックしたときに青い部分に日付が表示されるようになります。
<template>
<v-app>
<v-container>
<v-card>
<h1>Hello Nuxt</h1>
<v-date-picker v-model="date"></v-date-picker>
</v-card>
</v-container>
</v-app>
</template>
<script>
export default {
data: () => ({
date: "",
}),
};
</script>
script部分を足すだけではなく、v-date-pickerにv-modelを追加するのを忘れないでください。
JavaScriptの基本
まず最初にいきなりハードルの高いexport defaultの宣言があります。大半の記事ではこの部分を「おまじない」と言っていますが、この記事では解説していきます。そのためにも、JavaScriptの基本を押さえておきます。前提として、C言語やJavaなどの他のプログラミング言語を授業で習ったことぐらいはある方を対象にしています。
JavaScriptでは変数に型がありません。C言語やJavaでいうところのintやdouble, Stringのようなものです。ですので型を気にせず変数を使えます。
a = 123
a = 'hello'
一行目では数字の123をaという変数に代入していますが、2行目では文字列を代入しています。こんなことをしてもJavaScriptは動作します。ただ、こういう実装はやめた方がよいです。TypeScriptでは型を明確に定義しますが、型を定義しないと思わぬバグを引き起こします。
次に関数(メソッド)はfunctionとして定義します。定義の方法は二種類あります。
function test(a, b) {
return a + b;
}
test = function(a, b) {
return a + b;
}
どちらも同じ意味になります。一般的には上の宣言ですが、JavaScript的には下の宣言の方が好まれます。理由としてはfunctionを省略できるからです。functionを省略するには=>を引数と関数本体の間に入れます。
test = (a, b) => {
return a + b;
}
さて、returnするだけの関数なら{}やreturnも省略できます。
test = (a, b) => a + b;
ずいぶんシンプルになりました。JavaScriptではこの省略が一般的に使われるので覚えてください。TypeScriptでも同様になります。
次にJavaScriptのデータ構造です。難しことはなく、以下の2種類のみです。
リスト
array = [a, b, c] のように記述する。array[0]でa、array[1]でbの値を取得できる。array.push(d)でdの値を末尾に追加、array.pop()で末尾の要素を取得(削除)できる。
オブジェクト
obj = { a: 123, b: 456, c: 'hello' } のように記述する。obj['a']で123を取得できる。また、obj.aでも同様に取得できる。
リスト・オブジェクトの両方で変数にはなんでも使えます。つまり前述した関数を使うことも可能です。
obj = {
a: 123,
b: 456,
c: function () {
return 123 + 456
},
};
cの関数を呼び出すにはobj.c()とすれば実行できます。少し脇道に逸れますが、こういう関数を書きたくなりますよね。
obj = {
a: 123,
b: 456,
c: function () {
return this.a + this.b
},
};
このソースは正常に動作します。obj.c()を実行すると123+456の結果として579が得られます。一方で下記のソースは正常に動作しません。
obj = {
a: 123,
b: 456,
c: () => this.a + this.b,
};
obj.c()を実行するとNaNが返されます。cの関数内にあるthis.aがundefinedとなるためです。これにはJavaScriptで一番つまづく人が多いthisの使い方に依存します。これはまた別記事で解説します。
さて、ちょっと前に戻って省略記法の関数の書き方でオブジェクトを返すにはどう記述すればよいでしょうか。こんな風に書こうと思うかもしれません。
test = () => { a: 123, b: 456 }
しかしこれはJavaScriptの文法として正しくありません。{}の中身は関数の中身の処理として扱われてしまうためです。つまり、こう書いたのと同じです。
test = function () {
a: 123, b: 456
}
これでは意味が通らないですね。そのため、省略記法でオブジェクトを返すには次のように書きます。
test = () => ({ a: 123, b: 456})
返り値となるオブジェクトを()で囲うと、オブジェクトを返すことができます。
さて、これを踏まえてひとまず最初のscriptを見てみましょう。
export default {
data: () => ({
date: "",
}),
};
export defaultは次回に説明しますが、その後に書かれているものが何かは分かるようになりました。export defaultの後ろに書かれているのはdataが入ったオブジェクトで、そのdataは{ date: "" } というオブジェクトを返す関数になっています。ややこしいですね。
ひとまず、JavaScriptの基本としては以上です。他にもfor文やif文など基本としてやるべきことはたくさんありますが、必要に応じて解説します。
次回はVueファイルの中身にあったexport defaultやその中のデータの宣言方法などを解説していきます。