tomoyaki BLOG

いちSEの学習記録

第3章 Vueプログラミングの基本『Vue3 フロントエンド開発の教科書』を読む(3/n)

前回の続き。この章は予想以上に理解に時間がかかってしまった。

コンポーネントとは

基本構文

  • マスタッシュ構文
    • {{変数名}} で表現する。
    • スクリプトブロック()で用意した変数を表示するための構文。
  • テンプレートブロック()で利用する変数(テンプレート変数)の定義には、ref関数を利用する

      const name = ref("田中太郎");
    
    • ref() 関数は、事前に Vue.js 本体からインポートしておく必要がある。

これで、スクリプトブロックで用意した変数をテンプレートブロックで利用することができた。

<script setup lang="ts">
import {ref} from "vue";

const name = ref("田中太郎");
</script>

<template>
<h1>こんにちは!{{ name }}さん!</h1>
</template>

以前Vue2をほんの少々かじっていたので、Vue3でのOptions APIからComposition APIの書き方の変わりっぷりに戸惑う。変わりすぎではないか・・・?

リアクティブシステム

  • リアクティブとは、変数の値に連動して表示内容が自動で変化すること
  • リアクティブ変数の用意と値の書き換えは以下のように行う。
const 変数名 = ref(値);
変数名.value = 新しい値;

本章内に「ref()を使用して宣言するとリアクティブになり、ref()を使用しないとリアクティブにならない」という記述があったが、Vue3.2.45のバージョンで変更があったらしく、いずれもリアクティブな変数として動作していた。こちらのサイトが参考になった。

computed()

半径を乱数で取得し1秒後ごとに円の面積を求めるプログラムを、何も考えずに書くと以下のようになる。

computed()使用前

<script setup lang="ts">
import { ref, computed } from 'vue'

// 半径の初期値を乱数で取得
const radius = ref(Math.round(Math.random() * 10))
// 円周率のテンプレート変数を用意
const PI = ref(3.14)
// 半径のテンプレート変数に新しい乱数を1秒ごとに格納
setInterval((): void => {
  radius.value = Math.round(Math.random() * 10)
}, 1000)
</script>

<template>
  <p>半径{{ radius }}の円の面積を円周率{{ PI }}で計算すると、{{ PI * radius * radius }}</p>
</template>

Vueのスタイルガイドいわく、Mustache構文内で計算を行うことは避けるべきとされている。Mustache構文内で計算しないバージョンに書き換える必要がある。

以下のように computed()で書き換えることで、areaに依存している(計算式を構成する)変数の更新がトラックされるようになり、結果 area の値も1秒ごとに更新される。

computed()使用後

<script setup lang="ts">
import { ref, computed } from 'vue'

// 半径の初期値を乱数で取得。
const radiusInit = Math.round(Math.random() * 10)
// 円周率のテンプレート変数を用意。
const PI = ref(3.14)
// 半径のテンプレート変数を用意。
const radius = ref(radiusInit)
// 円の面積の算出プロパティを用意。
const area = computed((): number => {
  return radius.value * radius.value * PI.value
})

// 半径のテンプレート変数に新しい乱数を1秒ごとに格納。
setInterval((): void => {
  radius.value = Math.round(Math.random() * 10)
}, 1000)
// area.value = 300;
</script>

<template>
  <p>半径{{ radius }}の円の面積を円周率{{ PI }}で計算すると、{{ area }}</p>
</template>

reactive()

  • 複数データをオブジェクトとして扱い、まとめてリアクティブにする関数のこと。いまのところ使い道はよくわかってない。
<script setup lang="ts">
import {reactive, computed} from "vue";

// リアクティブなテンプレート変数をまとめて用意。
const data = reactive({
    PI: 3.14,
    radius: Math.round(Math.random() * 10)
});
// 円の面積の算出プロパティを用意。
const area = computed(
    (): number => {
        return data.radius * data.radius * data.PI;
    }
);
// 半径のテンプレート変数に新しい乱数を1秒ごとに格納。
setInterval(
    ():void => {
        data.radius = Math.round(Math.random() * 10);
    },
    1000
);
</script>

<template>
    <p>半径{{data.radius}}の円の面積を円周率{{data.PI}}で計算すると、{{area}}</p>
</template>

Vueプロジェクトの構成と動作原理

  • dist

    • デプロイ用ファイルセット
    • npm run build 実行後に一通り生成される。
    • このフォルダ一式をWebサーバにデプロイし、index.htmlをブラウザに読みこませることでVueアプリケーションが動作する。
    • ただし、開発段階で上記手順をいちいち踏むのは面倒なので、Vueプロジェクトフォルダのまま起動できる機能をViteが提供してくれている。
  • 動作原理としては以下。

    • index.htmlからmain.tsが実行される
    • main.ts内でApp.vueを読み込む
    • App.vueから各コンポーネントを呼び出す

プロジェクト構成と動作原理について、これまで曖昧な理解だったが本章を読んでだいぶ頭の中が整理された。本書はVueの根本的な仕組みと、「なぜそうなるのか」という部分にまで踏み込んで丁寧に解説をしてくれているのでありがたい。


*1: 細かいが、一般的には単一ファイルコンポーネントSFC)という名称が定着していると思われる。例:Vue.js公式ドキュメント