vue3を導入しようとして挫折した話



#はじめに
実PRJでvue3を導入しようとしたけど、PRJ途中で断念した話をまとめます。
巷ではCompositionAPIやら複数の双方向データバインディングやら話題ありますが、その辺りには到達することなく断念することになりました。とはいえ少し触ったので、「お、これいけてるやん！」というものも紹介しつつ、なぜ断念したかを綴ります。

---

#vue ３
「Vue 3」は、JavaScriptフレームワークVue.jsの次期バージョンで、2016年にリリースされた「Vue 2」以来のメジャーバージョンアップ。vue 2から記載方法が変わった点もあるが、割と互換性もある（気がした）

---

#便利だと思った機能
##`v-on:click`をcomponentに指定しても動くように
vue 2までだと、componentに対して`v-on:click`を指定しても動作しません

---

```vue:動かない
<template>
<div>
 <childComponent v-on:click="test" />
</div>
</template>
<script>
import childComponent from "@/components/chiledComponent";
export default {
 components: {
   childComponent,
 },
 methods: {
  test(): {
   alert("test")
  }
 }
}
</script>
```
---

なので、次のように記載する必要がありました。

---

```vue:これは動く
<template>
<div>
 <childComponent v-on:click.native="test" />
</div>
</template>
<script>
import childComponent from "@/components/chiledComponent";
export default {
 components: {
   childComponent,
 },
 methods: {
  test(): {
   alert("test")
  }
 }
}
</script>
```

---

これがvue 3だと

```vue:vue3だと動く
<template>
<div>
 <childComponent v-on:click="test" />
</div>
</template>
<script>
import childComponent from "@/components/chiledComponent";
export default {
 components: {
   childComponent,
 },
 methods: {
  test(): {
   alert("test")
  }
 }
}
</script>
```

---

のように記述することができます。
なのでタグが純粋なhtmlタグなのかcomponentタグなのか気にせず開発を進めることができます。

---

## build時の環境変数指定が楽に

> 本機能はvue 3ではなくVue CLI3の機能でした。ご指摘いただきありがとうございました。ただいずれにしろ便利だと思ったので内容はそのまま掲載いたします。

開発時はdev環境、ユーザーテスト環境、本番環境などの環境ごとにAPIの向き先など環境変数を変更したいニーズがあると思います。vue 2では環境変数がデフォルトではconfigディレクトリ以下にそれぞれ
- dev.env.js
- prod.env.js
- test.env.js
が用意されていますが、もっと環境を分けたい場合はwebpackコンフィグファイルあたりをいじる必要がありました。
Nuxt.jsではcrossenvやdotenvを`npm i`してnuxt.config.jsファイルをいじるようなことをやってたかと思います。
vue 3ではその辺りをかなり良しなにやってくれたのが感動しました。

下記手順で環境ごとのbuildを簡単に作成できます。

---

###1. プロジェクト直下に.env.環境変数の命名で環境変数ファイルを作成

```:Project
├─.env.production
├─.env.uat
└─.env.dev
```

---

###2. 「.env.環境変数」のファイルにVUE_APP_XXXの命名規則で変数を定義する

変数のプレフィックスに`VUE_APP_`を記載するのを忘れないようにしましょう。

```:env.dev
VUE_APP_REST_URL=https://testapi/v1/
VUE_APP_S3BACKET_URL=http://bucket.s3-ap-northeast-1.amazonaws.com
```

---

###3. package.jsonの`scripts`に下記を追記
--mode 以降を.env.環境変数の環境変数と対応させる

```json:package.json
{
 "scripts": {
  "build:dev": "vue-cli-service serve --mode dev",
  "build:uat": " vue-cli-service serve --mode uat",
  "buld:production": "vue-cli-service serve --mode producion"
 }
}
```
.vue内では`process.env.VUE_APP_REST_URL`のように記載すれば環境変数を参照できる

---

##オブジェクトや配列のバインディング改善

vue 2までの場合、配列要素の更新やオブジェクトのプロパティ追加削除を画面に反映させるには`Vue.set`や`Vue.delete`で間接的に操作する必要があったが、vue 3ではそれが不要となった。

```js:vue3
/* これで更新できる */
this.array[0] = this.inputValue
```

---

# なんでvue3を諦めたの？
vue3のメジャーアップデートの恩恵にはあまり与っていないにせよ、上記だけでもなかなかメリットがあるように見られたが、下記のような流れで断念。

---

## デザイナ「そういえばこのデザインbootstrap前提で作ってるよ」
そうなんです、2020年9月時点ではbootstrap-vueがvue3に対応していなかったのです。
でも、ここまでであれば開発チームはまだ心は折れません。所詮デザインなんてCSSで頑張ればbootstrapなんていらないよ。

---

## デザイナ「ダイアログはこのライブラリのイメージで作ったから、ライブラリ入れたら一発だよ」
bootstrapの流れからお察しの通り、ダイアログのライブラリも残念ながらまだvue3には対応していませんでした。

ここで開発メンバーも自前でダイアログのデザイン実装は厳しいと根を上げ、PRJ途中でNuxtに移行（笑）したのでした。

---

#じゃあどうするのが正解だったの？

ここはぶっちゃけあんまり解はないのかなと思います。プロジェクトの納期を優先するのであれば、実績やリファレンスが豊富な安定版を使うべきだし、エンジニアとして最新を追い求めたいのであれば多少困難でも最新版を積極導入すればいいと思います。技術力がとても高ければ最新入れても大抵のことは独力解決できるだろうし。

---

今回に関してはPRJの早い段階で見切りを付けられたので進捗にもさほど影響しなかったし、少しだけだけど最新バージョンをいろいろ調べつつ悩みつつ触ることで多少なりとも知見が増えたので、結果的には良かったのでは、と個人的には思っています。

---

vue 3に世の中が追いついてきたらまたPRJ導入を検討したいなと思いました。