はじめに
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のテンプレート記法は、別記事で詳しく説明しているので参考にしてください。