僕なりの Vue3 備忘録

# ダウンロードとインストール



CDNを利用しない、Vite環境を用意しない

以下のリンクにアクセスして表示されたコードをコピペ

- https://unpkg.com/vue@3/dist/vue.esm-browser.js
- https://unpkg.com/vue@3/dist/vue.esm-browser.prod.js（本番向けビルド）

以下のように配置することができる

```
todo  //プロジェクトのディレクトリ
├── css
│   └── style.css
├── index.html
└── js
    ├── App.js
    ├── components
    │   ├── TodoApp.js
    │   ├── TodoForm.js
    │   └── TodoList.js
    ├── main.js
    ├── vue.esm-browser.js //ES モジュールビルド
    └── vue.esm-browser.prod.js //ES モジュールビルド（本番向けビルド）
```



# データの扱い



## 受渡し

- props と emit を使う
- provide と inject を使う
- Pinia （状態管理ツール）を使う



## ぶつかった問題



### 疑問

BEから全データを持ってきて、FEで加工するのか、BEでデータを加工したものをFEに持ってくるのか？

どちらのやり方も要件や仕様によると思うが、それぞれの一般的なメリットデメリットを述べた上で、実例をあげていく。

最後に一括置換でhogeとかfugaとか無難なものに変えればいいかね？



### メリットデメリットの調査

#### ChatGPT

> ### 1. フロントエンドでデータを加工:
>
> **利点**:
>
> - **柔軟性**: 同じデータセットを異なる方法で何度も表示やフィルタリングが可能。
> - **サーバーリソースの節約**: サーバーは原始的なデータを返すだけでよく、再計算の必要がありません。
> - **レスポンシブなUI**: 一度データをフロントエンドに持ってくれば、ユーザーが異なるビューやフィルタを試す際の遅延が最小化されます。
>
> **欠点**:
>
> - **大量のデータ**: クライアントサイドでの大量のデータの処理は、パフォーマンスの低下や遅延を引き起こす可能性があります。
> - **再利用性の低下**: 他のクライアントやサービスが同じ加工データを必要とする場合、同じロジックを再実装する必要があります。
>
> ### 2. バックエンドでデータを加工:
>
> **利点**:
>
> - **効率**: データベースやサーバー側のツールは、大量のデータを効率的に処理するために最適化されています。
> - **一貫性**: すべてのクライアントが同じソースからデータを取得するため、データの一貫性が保たれます。
> - **セキュリティ**: 一部のビジネスロジックやデータの詳細をクライアントから隠すことができます。
>
> **欠点**:
>
> - **遅延**: すべてのデータ変更やリクエストに対してサーバーとの通信が必要。
> - **オーバーヘッド**: 多くのエンドポイントやAPIのバージョンを管理する必要があります。
>
> ### 結論:
>
> - **小～中規模のデータ**: フロントエンドでの処理が適している場合が多い。
> - **大規模なデータ** や **複雑な加工**: バックエンドでの処理が推奨されます。



#### 記事

https://qiita.com/SallyCinnamon/items/510ae5e26c18dee53bf8

この記事はデータのフォーマットは（日付の出力方式等）フロントエンドでやろうね。

なぜなら、そのAPIの汎用性を著しく落としてしまうから、と書いてあった。



https://qiita.com/ryo88c/items/0a3c7861015861026e00

> 車で家族を駅まで迎えに行くという行動は非常に具体的且つ、複雑なプロセスを内包しています。簡単に言えば GET も POST も含まれています。
> このような場合には車で家族を駅まで迎えに行くという行為を示すことのできるエンドポイントの組み合わせを考えるべきです。つまり、車で家族を駅まで迎えに行くという行為は複数のエンドポイントを組み合わせたトランザクションと解釈すべきです。
>
> 1. `GET /cars` をリクエストして自分の車の ID を得る
> 2. `POST /cars/1`（リクエストボディは `item=/me`）をリクエストして車に乗る
> 3. `GET /families?location=station` をリクエストして駅にいる家族の ID を得る
> 4. `GET /families/2/locations` をリクエストして家族のいる場所を得る
> 5. `POST /locations/3`（リクエストボディは `item=/cars/1`）をリクエストして家族が待っている場所に車を向かわせる
> 6. `PUT /cars/1`（リクエストボディは `item=/families/2`）をリクエストして家族を車にのせる
>
> そもそもとして「車で家族を駅まで迎えに行く」という行為を単一のエンドポイントで示した場合、可用性が非常に低くなります。
> **API は出来る限り事象を抽象的に指し示し、組み合わせによって具体性を制御できるようにすべきです。**
> 「車で|家族を|駅まで|迎えに行く」のように、行為を構成する要素に分割することで、どのように API を抽象化すべきかを判断できます。

↓こういうのが欲しかった。

> ## フィルタ・ソート・検索をリクエストパラメータでやるべき理由
>
> > フィルタ・ソート・検索はリクエストパラメータでやろう
>
> との記載がありますが、何故そうすべきかが言及されていませんでしたので補足します。リクエストパラメータでやるべきなのはそうですが、フィルタや検索といった行為は、エンドポイントとして定義されていない事象の集合を、エンドポイントとして定義されている集合の部分集合として取り出す事を指します。つまり、フィルタや検索で得たい集合はそもそもとしてエンドポイントとして存在していません。
>
> また、`/books?author=john&title=my_book` という URI が任意の本をフィルタすると考えた場合、仮にフィルタやソートのリクエストパラメータをエンドポイントに加えるとして `/books/john/my_book` と `/books/my_book/john` はどう異なるのでしょうか。
> 同一の事象を指し示すのであるならばエンドポイントも同一であるべきです。事象の属性間に順序を見出すことは難しいですが、URI で表現されるエンドポイントには順序があります。
>
> これらがフィルタ・ソート・検索をリクエストパラメータでやるべき理由です。



# Composition API



## プロジェクトの作成



### プロジェクトの作成の前に知っておくこと

`create-vue`でプロジェクトを作る

参考： https://github.com/vuejs/create-vue

> The recommended way to start a Vite-powered Vue project

らしい、から、とりあえず`create-vue`使っておけばいいのか？と思ったら、

https://zenn.dev/sa2knight/scraps/383dbcb2634153

こんな記事を見つけた。まとめると、

- Vueアプリケーションを新規で作るには、`create-vue`と`vite`のどっちかを使うといいよ。
- 使い分けは、`vite`は必要最低限のエコシステムが、`cretate-vue`は手厚いエコシステムが入ってくるよ。
- サクッと試す場合は`vite`で、がっつアプリケーションを作る時は`create-vue`で。

らしい。今回作るものはそんなに重くはなさそうだけど、、、記事に従って`create-vue`にしてみる。

ちなみに、エコシステムは

> 互いにメリットを与えながら存在するという依存関係 （参考：https://webpia.jp/ecosystem/#index_id1）

らしい。たぶん依存関係にあるパッケージとかモジュールとか、それらの総称なのかな？



### 作成

```bash
# プロジェクト作成
$ npm init vue@3 vue3-lab
> all No

$ cd vue3-lab

# 外部パッケージインストール
$ npm install

# 開発環境起動
$ npm run dev
```

こちらhttp://localhost:5173/ にアクセスすると、無事できている！！！



## 基本

### `<script setup>`ってなんだ？

公式サイト：https://ja.vuejs.org/api/sfc-script-setup.html  によると、

> <script setup> は単一ファイルコンポーネント（SFC）内で Composition API を使用するコンパイル時のシンタックスシュガー（糖衣構文）です。

らしい。今よく理解できるのは、コードがスッキリ書けるよ！ということかな。。。

こちらの記事も分かりやすかった。参考：https://qiita.com/kotobuki5991/items/50a41e4344d2b2047596#%E7%B5%90%E8%AB%96-script-setup%E3%81%A8%E3%81%AF

こちらも。参考：https://zenn.dev/azukiazusa/articles/676d88675e4e74

こちらも。参考：https://b1san-blog.com/post/vue/vue-3-composition-api/

また改めてどこかで、まとめたいです。



### `ref`ってなんだ？

こちらの記事にいい説明があった。参考：https://b1san-blog.com/post/vue/vue-3-composition-api/ （こちらの記事もすごく勉強になったので、今度がっつり勉強したいです。）

`<script setup>`で定義したプロパティ等をリアクティブにするために必要らしい。

例えば、

```vue
<template>
  <div>{{ text }}</div>
  <button @click="changeText">click</button>
</template>

<script setup>
let text = 'Hello World!!';
const changeText = () => { text = 'Hello Again' };
</script>
```

として、clickしてもtextは変わりません。

これを、

```vue
<template>
  <div>{{ text }}</div>
  <button @click="changeText">click</button>
</template>

<script setup>
import { ref } from 'vue';
let text = ref('Hello World!!');
const changeText = () => { text.value = 'Hello Again' };
</script>
```

とすることで、clickするとtextは変わります。

つまり、

- refはリアクティブにするために必要

なんですね！



## 関数と算出プロパティとの違い

算出プロパティ：`computed`

- 関数

    ```vue
    <script setup>
    
    function stockQuantity() {
      return items.value.filter(item => item.soldOut === false ).length
    }
      
    function getDate() {
      return Date.now()
    }
    </script>
    
    <template>
      <div>商品数：{{ stockQuantity() }}</div>
      <div>現在時刻：{{ getDate() }}</div>
    <template>
    ```

    

- 算出プロパティ

    ```vue
    <script setup>
    import { ref, computed } from 'vue'
    
    const stockQuantityComputed = computed(function() {
      return items.value.filter(item => item.soldOut === false ).length
    })
    
    const getDateComputed = computed(function() {
      return Date.now()
    })
    </script>
    
    <template>
      <div>商品数：{{ stockQuantityComputed }}</div>
      <div>現在時刻(computed)：{{ getDateComputed }}</div>
    </template>
    ```



算出プロパティを利用すると、オブジェクトで定義したプロパティと同じように扱うことができる。そのためtemplateの中では`()`が不要。

大きな違いとして 算出プロパティにはキャッシュ機能があるため、値の更新タイミングが異なる。

- 関数：

    - `template`や他のメソッドから呼び出されるたびに実行

    - キャッシュされないため、値に変化がなくても、再度呼び出されると再計算される。
    - 常に最新のデータに基づいて動作するが、計算が重い場合、パフォーマンスに影響があることがある。

- 算出プロパティ：

    - `items`が更新された時
    - 依存関係に基づいてキャッシュされる。
    - 依存しているデータが変更されない限り、再計算されず、キャッシュされた結果が使用される。
    - 依存データが変更されたときのみ再計算されるため、計算が重い場合でも効率的。
    - レンダリングの最適化に役立つ