はじめに
本連載では、JavaScriptを利用して動的なWebページを構築できるフレームワークVue.jsを、データの型指定ができるように拡張されたAltJS(コンパイルしてJavaScriptにする言語)であるTypeScriptで活用する方法を、順を追って説明しています。
前回はVue.jsなどのプロジェクトを高速で生成・実行できるコマンドライン(CUI)ツール「Vite」について説明しました。本連載ではプロジェクト生成時にさまざまなカスタマイズを行う見込みなので、従来より提供されているVue.js専用のCUIツール「Vue CLI」を引き続き利用していきます。
これまでは主に、CUIツールが生成したソースコードをほぼそのまま実行してきましたが、自分が思うような処理を行わせるためには、Vue.jsのソースコードを自分で実装する必要があります。今回はその一歩として、Vue.jsでさまざまなデータを入出力して、画面に反映させるための基本機能を説明します。本記事のテーマであるTypeScriptを利用した記法も併せて紹介していきます。
対象読者
- これからVue.jsに入門したい方
- Vue.jsやTypeScriptについて一から学びたい方
- Vue.jsで動的なページを作る基本を知りたい方
必要な環境
本記事のサンプルコードは、以下の環境で動作を確認しています。
- Windows 10 64bit版
- Node.js v16.13.0 64bit版
- Vue CLI 4.5.15
- Vue.js 3.2.20
- TypeScript 4.1.6
- Microsoft Edge 95.0.1020.40
サンプルコードを実行するには、サンプルのフォルダーで「npm install」コマンドを実行してライブラリーをダウンロード後、「npm run serve」コマンドを実行して、Webブラウザーで「http://localhost:8080/」を表示します。
データの入力と画面への出力
動的なWebページでは、入力されたデータを反映して表示内容を変更する処理が頻繁に行われます。このような処理をVue.jsで実現する方法を、図1のサンプルで説明します。このサンプルでは、画面に入力した内容をもとに画面表示を行います。
図1の通り動作させるには、Webページ全体(のコンポーネント)に対応するsrc/App.vueファイルを編集します。まず、<script>部でリスト1の通り、表示するデータなど、コンポーネントの動作を実装します。
<script lang="ts"> import { defineComponent } from "vue" export default defineComponent({ // コンポーネント処理内容の記述 ...(1) // データ ...(2) data() { return { no: 1, company: 'Apple', name: 'iPhone 13', url:'https://www.apple.com/' as string, // 明示的にstringを指定 ...(2a) weight: 173 as number // 明示的にnumberを指定 ...(2b) } }, // 算出プロパティ ...(3) computed: { fullName(): string { return `${this.name} (${this.company})` }, }, // メソッド ...(4) methods: { getWeightText(weight: number): string { // weightはnumber型なのでtoFixedメソッドが利用できる ...(4a) return `重量:${weight.toFixed(1)} g` } } }) </script>
過去記事でも説明した通り、TypeScriptの型推論を利用するために、defineComponentメソッド(1)の引数としてデータなどの処理内容を記述します。
画面に表示するデータはdata()メソッド(2)の戻り値として記述します。TypeScriptの型推論により、初期値に設定したデータから型が決定されます。ここではnoはnumber型、companyとnameはstring型になります。明示的に型を指定したい場合は(2a)(2b)の通り「as <型>」を後ろに記述します。この記述法は型アサーションと呼ばれます。
(3)の「computed:」で記述される処理は「算出プロパティ」と呼ばれ、データを加工して出力する読み取り専用のプロパティを定義できます。ここではnameとcompanyを接続して取得するfullNameプロパティを定義しています。「fullName(): string」記述により、この算出プロパティがstring型であることを表します。
(4)はメソッドの実装で、ここではnumber型の引数weightから、重量を表す文字列を加工して出力するgetWeightTextメソッドを実装しています。weightにnumber型が指定されているので、数値を固定小数点表記にするtoFixedメソッドが利用できます(4a)。
[補足]型の不一致によるエラー
TypeScriptを利用したVue.jsプロジェクトでは、型の不一致はエラーになります。例えばリスト1(3)の算出プロパティfullNameの戻り値をnumberに変更すると、TypeScriptコンパイラーや開発環境でエラーになることが確認できます。
表示内容を表す<template>部はリスト2の通りです。
<template> <!-- v-modelでフォーム内容と変数を紐づけ ...(1)--> <div>番号:<input v-model.number="no" /></div><!-- 数値型を指定 ...(1a)--> <div>会社:<input v-model="company" /></div> <div>機種:<input v-model="name" /></div> <div>重量:<input v-model.number="weight" /></div><!-- 数値型を指定 ...(1b)--> <div>URL:<input v-model="url" /></div> <hr> <!-- データの反映 ...(2)--> <div> 【No.{{ no }}】 <!-- 変数を参照 ...(2a)--> {{ fullName }} <!-- 算出プロパティを参照 ...(2b)--> </div> <div> {{ getWeightText(weight) }} <!-- メソッドの実行結果を参照 ...(2c)--> </div> <div> Webページ: <a v-bind:href="url" target="_blank"> <!-- url変数をhrefに反映 ...(2d)--> <!-- 「:href」は「v-bind:href」の省略記法 ...(2e) <a :href="url" target="_blank"> --> {{ url }} </a> </div> </template>
<template>部では、<script>部で定義した変数やメソッドなどをもとに画面表示を記述します。(1)の「v-model="<変数名>"」は、 <input>タグの入力内容を、<script>部のデータと紐づける(いわゆる「双方向データバインディング」を設定する)記述です。
このv-modelのように、HTML要素に指定するVue.js独自の属性記述を「ディレクティブ」と呼びます。v-modelでは、特に型を指定しないと文字列として紐づけられますが、(1a)(1b)の通り「v-model.number」とすると、入力値が数値であると指定できます。
データを反映する(2)の箇所では、2重の中カッコ「{{ }}」で変数名を囲んだ記述で、変数(2a)や算出プロパティ(2b)、メソッドの実行結果(2c)を画面に表示するよう実装しています。また、(2d)の通り、表示内容ではなくHTMLタグの属性に変数の内容を反映させたいときは、v-bindディレクティブを利用して「v-bind:<属性名>="<変数名>"」と記述します。ここでは<a>タグのリンク先(href属性)に、url変数の内容が設定されます。なお、v-bindディレクティブでは(2e)の省略記法が利用できます。