Vue3の始め方

# はじめに

Vue.js 3.0リリースに併せて、Vue.jsをハンズオン形式で学習する書籍を出版しました。書籍では、Vue3への移行情報や新機能の中心になっているComposition APIを解説しています。書籍の宣伝を兼ねて、2020年10月時点のVue3の取り組み方について解説します。多大に宣伝を含みますが、ご了承ください。
最初に結論を。しばらくは公式ライブラリとUIコンポーネントライブラリの対応状況をウォッチし、Vue3の本格的な採用は様子見することを個人的におススメします。

# Vue3の新機能

https://v3.vuejs.org/guide/migration/introduction.html#notable-new-features

Vue3の新機能をいくつか取り上げて紹介します。

## Composition API

https://v3.vuejs.org/guide/composition-api-introduction.html

新しく導入されたコンポーネントの記述スタイルです。
次のプラグインを使うことで、Vue2でも一部の機能を除いて利用可能です。

* https://github.com/vuejs/composition-api

書籍ではComposition APIを中心に解説しています。
Vue3と言えばComposition API、という感じでネット上にも情報が溢れていますのでここでは紹介を割愛します。

## Teleport

https://v3.vuejs.org/guide/teleport.html#teleport

`teleport`タグで囲まれたコンテンツを、`to`で指定した場所に描画させることができる機能です。
公式ドキュメントのサンプルは次のとおりです。記述方法を確認してみてください。

```
template: `
  <button @click="modalOpen = true">
    Open full screen modal! (With teleport!)
  </button>

  <teleport to="body">
    <div v-if="modalOpen" class="modal">
      <div>
        I'm a teleported modal! 
        (My parent is "body")
        <button @click="modalOpen = false">
          Close
        </button>
      </div>
    </div>
  </teleport>
`,
```

```
template: `
  <h2>This is a parent component</h2>
  <teleport to="#endofbody">
    <child-component name="John" />
  </teleport>
`
```

## Fragments

https://v3.vuejs.org/guide/migration/fragments.html

公式ドキュメントのサンプルを見ればわかると思いますが、`template`タグ直下に複数のタグを並べることができるようになりました。

```
<template>
  <header>...</header>
  <main v-bind="$attrs">...</main>
  <footer>...</footer>
</template>
```

# Breaking Changes

https://v3.vuejs.org/guide/migration/introduction.html#breaking-changes

Vue3のBreaking Changesをいくつか取り上げて紹介します。

## Global API

インスタンスの生成やグローバルコンポーネントの登録など、グローバルAPIがインスタンスAPIに変更されています。
また、`Vue.nextTick`は次のようにインポートして使うなど、APIの見直しが行われています。

```
import { nextTick } from 'vue'
```

## v-modelの変更

`:value`が`:modelValue`に、`@input`が`@update:modelValue`に変更されました。
`v-bind`ディレクティブの`.sync`修飾子が廃止され、v-modelを使う形になります。
また、次の公式ドキュメントのサンプルのように、複数のv-modelを設定できるようになりました。

```
<ChildComponent v-model:title="pageTitle" v-model:content="pageContent" />
```

## フィルターの廃止

メソッドで代用が効くため、Vue3で廃止されました。

## $listenersの廃止

Vue3では、イベントリスナーは`$attrs`にマージされたため、`$listeners`はVue3で廃止されました。

## .native修飾子の廃止

`v-on`ディレクティブの`.native`修飾子が廃止されました。

## Events API

`$on`、`$off`、`$once`が廃止されました。

# 実験的な機能

次の機能が試験的に実装されています。

* 単一ファイルコンポーネントの記述を簡潔にする機能  
[SFC Composition API Syntax Sugar `<script setup>`](https://github.com/vuejs/rfcs/blob/sfc-improvements/active-rfcs/0000-sfc-script-setup.md)
* `script`タグ内から、`style`タグに値を渡すことができる機能  
[SFC State-driven CSS Variables `<style vars>`](https://github.com/vuejs/rfcs/blob/sfc-improvements/active-rfcs/0000-sfc-style-variables.md)  
これによって、動的にスタイルを制御しやすくなります。
* Suspenseコンポーネント  
コンポーネントを描画する準備が整っていないタイミングで、代替の表示を行うことができます。
ローディング処理の実装に使えそうです。

# ライブラリの対応状況

https://github.com/vuejs/vue-next

Vue RouterがRCになりましたが、Vuexやその他周辺ライブラリはβの状態です。

## UIコンポーネントライブラリの対応状況

UIコンポーネントライブラリのVue3対応は、もうしばらく待つことになりそうです。Vue3への移行は、実質UIコンポーネントライブラリの対応待ちになるでしょうね。
メジャーなライブラリのVue3への対応が言及されているIssueを示しておきます。

* [BootstrapVue](https://github.com/bootstrap-vue/bootstrap-vue/issues/5196)
* [Buefy](https://github.com/buefy/buefy/issues/2505)
* [Element UI（Element Plus）](https://github.com/ElemeFE/element/issues/20061)
* [Quasar](https://github.com/quasarframework/quasar/issues/7836)

# クラススタイルにどう向き合うか

主流はComposition APIを使った記述スタイルになっていくことが予想されますが、サーバーサイドエンジニアに馴染みの深い、オブジェクト指向言語に似た記述スタイルを捨てがたい人も居るのではないでしょうか。
Vue.jsの公式リポジトリ内では、Vue3へのクラススタイルの導入は一旦見送られていますが、クラススタイルをサポートするライブラリはそうとも限りません。次のモジュールを使っている場合は、ライブラリの対応をウォッチしておくのが良さそうです。

* vue-property-decorator
* vuex-module-decorators

Vue3への対応について言及しているIssueはこちらです。

* [vue-property-decoratorのVue3対応について](https://github.com/kaorun343/vue-property-decorator/issues/294)
* [vuex-module-decoratorsのVue3対応について](https://github.com/championswimmer/vuex-module-decorators/issues/278)

# まとめ
公式ライブラリやUIコンポーネントライブラリなどの対応状況をウォッチしながら、Vue3の学習をしつつ準備を進めるのが良さそうです。
既存のアプリケーションを移行するにもそれなりの作業量が予想されるため、少しずつ準備を進めましょう。プラグイン`@vue/composition-api`を使った段階的な移行を検討するのもよいかもしれません。

# 書籍の紹介
<img width="300" src="https://github.com/ha6-6ru/vuejs-handson/raw/gh-pages/cover.jpg">
[書籍の情報サイト](https://github.com/ha6-6ru/vuejs-handson)

## 紹介
人気のJavaScriptフレームワークVue.jsにフォーカスし、フロントエンド開発の基礎から本格的なSPAの開発まで、ハンズオン形式で一歩ずつ、無理なく着実にステップアップしていきます。 さらに、2020年リリース予定のVue.js 3.0をいち早くキャッチアップ。Vue CLI 4に対応しつつ、Vue.js 2.xとの差分として新しい記述スタイル（Composition API）を併記するなど、バージョン移行を強力に支援します。

## 基本情報
* 著者: @ha6_6ru
* 出版社: 株式会社リックテレコム
* B5変型判／624ページ
* 2020年10月中旬刊行
* 出版社の紹介ページ  
http://web14.ric.co.jp/book/contents/book_1229.html
* [Amazonから購入](https://amzn.to/3jSI1tc) [楽天ブックスから購入](https://books.rakuten.co.jp/rb/16461447/?l-id=search-c-item-text-01) [hontoから購入](https://honto.jp/netstore/pd-book_30542369.html) [ヨドバシカメラから購入](https://www.yodobashi.com/product/100000009003335342/) [紀伊国屋書店から購入](https://www.kinokuniya.co.jp/f/dsg-01-9784865942293)