はじめに
Nuxt.jsは、Webページのユーザーインタフェース(UI)を構築できるVue.jsとともに、様々な追加機能をまとめて提供するフレームワークです。現在次期バージョン「Nuxt 3」が開発中で、2022年4月にリリース候補(RC)版がリリースされました。
前回は導入編として、Nuxt 3の概要を説明するとともに、Nuxt 3プロジェクトを生成・実行する方法や、Nuxt 2のプロジェクトでNuxt 3の機能を利用するNuxt Bridgeについて説明しました。今回は最初に、Nuxt 3を利用するのに欠かせないComposition APIやディレクティブといったVue.jsの基本文法を軽く説明します。次に、前回大まかに説明したNuxt 3プロジェクトの構造をもう少し細かく紹介するとともに、Vue.js単体では提供されないNuxt 3ならではの機能として、Webページに表示するデータを非同期で取得する「useAsyncData」「useFetch」の利用法を説明します。
対象読者
- Nuxt.jsでVue.jsの最新機能を使いたい方
- これを機会に最新のNuxt.jsで利用法を学びたい方
- Vue.jsにはないNuxt.jsならではの機能に興味がある方
必要な環境
本記事のサンプルコードは、以下の環境で動作を確認しています。
-
Windows 10 64bit版
- Node.js 16.15.0 64bit版
- Nuxt.js 3.0.0(リリース候補版)
- Microsoft Edge 101.0.1210.39
サンプルコードはNuxt 3のCLIツールで生成したものです(生成方法は前回記事を参照)。このサンプルコードを開発モードで実行するには、サンプルのフォルダーで「npm install」コマンドを実行してライブラリーをダウンロード後、「npm run dev」コマンドを実行して、Webブラウザーで「http://localhost:3000/」を開きます。
Nuxt 3の利用に欠かせない! Vue.jsの基本をおさらい
Nuxt 3を活用するには、ベースとなっているVue.js(Vue 3)の基本的な利用法を把握する必要があります。そこでまず、図1のサンプルを利用して、Vue.jsの基本的な利用方法を大まかにおさらいしていきます。
ページコンポーネントの構造
Webページの表示に対応するapp.vueファイルは、リスト1の構造を持っています。<template>部にWebページの外見をHTMLタグで記述し、<script>部にはWebページのデータや、振る舞いを表すメソッドをJavaScriptで記述します。
<template> ...Webページの外見を表すHTMLタグ... </template> <script lang="ts"> ...データやメソッドなどのJavaScript... </script>
Composition APIでWebページのデータや振る舞いを記述
<script>部の記述方法には、Vue 2までで利用されていた方法(Options API)のほか、Vue 3から正式サポートされた「Composition API」という方法があり、本連載ではComposition APIを利用していきます。図1のページの<script>部をComposition APIで実装したものはリスト2となります。
<script lang="ts">
export default defineComponent({ // ...(1)
setup() { // ...(2)
// 変数(reactive記述で画面から変更できるようにする) ...(3)
const param = reactive({
name: '吉川英一',
url: 'https://wings.msn.to/'
})
// 変数(読み取り専用、画面から変更しない) ...(4)
const phones = [
{
model: 'Galaxy S22',
vendor: 'Samsung'
},
(略)
]
// 算出プロパティ ...(5)
const nameWithSuffix = computed(() => {
return param.name + 'さん'
})
// メソッド ...(6)
const onClickButton = () => {
alert(`${nameWithSuffix.value}、こんにちは`)
}
// 変数・算出プロパティ・メソッドを返却 ...(7)
return {
param,
phones,
nameWithSuffix,
onClickButton
}
}
})
</script>
実装はdefineComponentメソッド(1)内のsetupメソッド(2)に行います。変数(3)は、前回記事ではrefメソッドを利用した方法を紹介しましたが、今回はもう一つの方法である、reactiveメソッド内に複数の変数を定義する方法で記述しました。refまたはreactiveを利用して記述した変数は、リアクティブな変数となり、画面からの操作で変更できるようになります。画面から変更しない変数(4)は、refまたはreactiveを利用せず、直接記述できます。
(5)は名前に「さん」をつける算出プロパティ、(6)はalertで挨拶を表示するメソッドです。最後に(7)で変数・算出プロパティ・メソッドを返却すると、<template>部で参照できるようになります。
<script setup>記述を利用すると、リスト2はリスト3の通り簡略化できます。
<script setup lang="ts">
// 変数(reactive記述で画面から変更できるようにする)
const param = reactive({
name: '吉川英一',
url: 'https://wings.msn.to/'
})
// 変数(読み取り専用、画面から変更しない)
const phones = [
{
model: 'Galaxy S22',
vendor: 'Samsung'
},
(略)
]
// 算出プロパティ
const nameWithSuffix = computed(() => {
return param.name + 'さん'
})
// メソッド
const onClickButton = () => {
alert(`${nameWithSuffix.value}、こんにちは`)
}
</script>
<script setup>タグ内に、リスト2でsetupメソッド内に記述した実装(return文以外)をそのまま記述すると、リスト2と同じ動作をするようになります。
ディレクティブでWebページにデータや振る舞いを反映
<script>部に記述したデータや振る舞いは、HTMLにVue.js独自の記述を組み合わせて<template>部に記述することで画面に反映します。リスト2(またはリスト3)の<script>部に対応した<template>部は、リスト4の通りとなります。
<h3>基本ディレクティブ1:変数値の設定と反映</h3>
<div>
<a v-bind:href="param.url" target="_blank"> <!--(1)-->
{{ param.name }} <!--(2)-->
</a>
</div>
<div>
名前:<input type="text" v-model="param.name"> <!--(3)-->
</div>
<div>
URL:<input type="text" v-model="param.url"> <!--(4)-->
</div>
<h3>基本ディレクティブ2:操作イベントへの対応</h3>
<div>
<button v-on:click="onClickButton">ボタン</button> <!--(5)-->
</div>
<h3>基本ディレクティブ3:繰り返しと条件分岐</h3>
<ul>
<li v-for="phone in phones" v-bind:id="phone.model"> <!--(6)-->
<span v-if="phone.vendor == 'Samsung'" style="color:blue"> <!--(7a)-->
{{ phone.model }} ({{ phone.vendor }})
</span>
<span v-else-if="phone.vendor == 'Apple'" style="color:red"> <!--(7b)-->
{{ phone.model }} ({{ phone.vendor }})
</span>
<span v-else style="color:green"> <!--(7c)-->
{{ phone.model }} ({{ phone.vendor }})
</span>
</li>
</ul>
変数値をWebページに反映するには、(2)の通り「{{ }}」で変数名を囲んで記述します。入力フォームで変数値を設定できるようにするには、(3)(4)の通り、入力フォームにv-model属性で変数名を指定します。(1)のv-bind:hrefは、HTMLタグのhref属性に変数値を反映します(単に「:href」とも記述できます)。(5)のv-on:clickはボタンのclickイベントに対応するメソッドを指定します(「@click」とも記述できます)。(6)のv-for、(7a)~(7c)のv-if・v-else-if・v-elseはそれぞれ、繰り返しと条件分岐を表し、ここではphones配列の各要素を、vendorプロパティの値により色分けして表示するようにしています。Vue.jsで利用するこの「v-***」属性を「ディレクティブ」と呼びます。これらVue.jsのテンプレート記法は、別記事で詳しく説明しているので参考にしてください。
