26
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

今までVue 2に慣れ親しんできたのでVue 3をキャッチアップする

Last updated at Posted at 2021-10-14

対象読者

Vue 2をこれまでやったことがあって今後Vue 3もキャッチアップしたい方
そのため本記事はVue 2をやってきた前提で説明します。

本記事を書こうと思ったきっかけ

  • 今後仕事などで触れる機会が出てきそう
  • Nuxtももうすぐバージョン3が出る
    (本当はこれの記事にしようと思ったが、ベータ版リリースが10/12(火)夜で丁度間に合わず)
  • Vuexも今後出るバージョン5で長年問題だったTypeScriptとの互換性が解消されるらしい
  • Composition APIの記事を読んでたらComposition APIが面白そうに感じた

とこんな感じでとりあえず少しずつ齧っていこうと思ったのがきっかけです。

Vue 3で新しく登場した主な機能と特徴

追加した主な機能はこちらとなります。
今回の記事ではComposition APIFragmentsを紹介します。

  • Composition API
  • Teleport
  • Fragments
  • Emits Component Option
  • Suspense(現時点では実験段階、本番環境での使用はまだダメ)

また、Internet Explorer11は非対応となりました。

どんな形でキャッチアップした?

公式のドキュメントを主に読みました(日本語化済み)。
ドキュメントにも記載がある通り、Vue 2を一通りやってきた人は「Vue 2からの移行」ページに書かれているページさえ読めば大丈夫です。

また下のサイトはVue 3の概要についてわかりやすく書いてくれていました。Vue2をずっとやってきた人はまずここを読むと頭に入ってきやすいと思います。

初期設定〜アプリの作成まで

公式リポジトリのREADMEを参考に設定しました。

アプリの作成

# Vue-cliがインストールされていない場合は↓でグローバルインストール
npm install -g @vue/cli # OR yarn global add @vue/cli

vue create [アプリ名]

特になければvue 3 presetを選択。
※勿論Vue 2と同じくManual installを選択し、下記の画像のように全部盛りにすることも出来ます。
スクリーンショット 2021-10-10 15.11.56.png

そしてnpm/yarnのインストールが完了してから、npm run serve or yarn serveすると、Vue 3アプリが立ち上がるはずです。

なおVue 3は上記のVue cliを使う以外にViteを使って作成することも出来ます。

VSCode拡張機能インストール

Vue3で使用するVSCodeの拡張機能はVeturではなくVolarが推奨されています。
そのためVeturを入れている場合、こっちはDisable(無効化)してください。

devtoolsのインストール

devtoolsがbeta版でないと3系に対応していないのでインストール&有効にします。
(安定版を入れている場合は安定版の方を無効にする)

Composition APIとは

<公式ドキュメント>
https://v3.ja.vuejs.org/guide/composition-api-introduction.html

Vue 2まで馴染みのあったコンポーネントの書き方はOptions APIと呼ばれるものでした。

// Options API

<script lang="ts">
import Vue from "vue";
import HelloWorld from "@/components/HelloWorld.vue";

interface DataType {
  count: number
  initilize: boolean
}

export default {
  name: "Home",
  data():DataType {
    return {
      count: 0,
      initilize: false
    }
  },
  computed: {
    message() {
      return `Count is ${this.count}`;
    }
  }
  methods: { ... },
}
</script>

ただし、この書き方はdata、computed、methodsといった宣言があるため、コンポーネントが持つロジックが大きくなるほど肥大化し、処理が追いにくくなる問題がありました(大規模アプリケーションだと尚更)。
そこでVue 3ではこうした問題に対処するため、Composition APIが登場しました。

// Composition API

<script lang="ts">
import { computed, reactive, onMounted, defineComponent } from "vue";
import HelloWorld from "@/components/HelloWorld.vue";

export default defineComponent({
  name: "Home",
  components: {
    HelloWorld,
  },
  setup() {
    const data = reactive({ count: 0, initilize: false });
    const message = computed(() => {
      return `Count is ${data.count}`;
    });
    return {
      data,
      message,
    };
  },
});
</script>

ただし、Composition APIが強制されているわけではなく、Options APIもVue 3では引き続き使用可能です。ケースバイケースで使い分けることが出来ます。

Composition APIの大きな変化かつ利点として、「コンポーネント特有のロジックを別ファイルに切り出すこと」が出来るようになりました。
このように切り出された処理はコンポジション関数(Composition Function)と呼びます。
(Reactをご存知の方はReact hooksに近いものと思っていれば大丈夫です)

これによって以下の恩恵が得られます。アプリケーション開発の規模が大規模になればなるほどこの恩恵はでかいでしょう。

  • 該当ロジックが別ファイルに切り出されることによって、コンポーネントのコードが整理されて見やすくなる
  • 同じロジックを複数のコンポーネントに何度も書く必要がなくなった

なお、定義するコンポジション関数の名前などは何でもいいですが、以下の形で書かれることが多いです。

  • src/composableフォルダ以下に定義したファイルを設置
  • 関数名をuseXXXにする
  • 拡張子はjsもしくはts

以下コンポジション関数の記載例となります。

// コンポジション関数<useUserNames>を定義
import { computed, ref } from 'vue'

export const useUserNames = () => {
  const userNames = ref<string[]>([])
  const getUserNames = async() => {
    userNames.value = await fetchUserNames()
  }
  const resultString = computed(() => {
    if(userNames.value.length === 0) {
      return 'No User Names'
    }
    return 'User Names have'
  })
  return {
    userNames,
    getUserNames,
    resultString
  }
}
// 定義したコンポジション関数を使ってコンポーネント側に表示
<template>
  <p>UserNames</p>
  <div v-for="userName in userNames">
    {{ userName }}
  </div>  
</template>

<script lang="ts">
import { computed, reactive, onMounted, defineComponent } from "vue";
import { useUserNames } from '@/composable/useUserNames'

export default defineComponent({
  name: "UserNames",
  async setup() {
    const {userNames , getUserNames, resultString} = useUserNames()
    await getUserNames()
    return {
      userNames,
      resultString,
    };
  },
});
</script>

Fragments

またVue 3ではもう一つ大きな新機能としてFragmentsが登場しています。

<公式ドキュメント>

Vue 2までは以下の例のようにコンポーネントのtemplateタグには一つしか入れ子を入れられませんでした。
そのため余分なdivタグを入れて対処しなければいけない状況が発生していました。

<!-- Vue 2までの書き方 -->
<template>
  <div>
    <h1>example</h1>
    <p>vue 3 example</p>
    <div>...</div>
  </div>
</template>

Vue 3ではtemplateタグに複数の入れ子を入れることが可能になり、余分なdivタグを入れる必要が
なくなり、テンプレートが見やすくなりました。

<!-- Vue 3で可能になった書き方 -->
<template>
  <h1>example</h1>
  <p>vue 3 example</p>
  <div>...</div>
</template>

サンプルコード/見たほうがいいリポジトリ

Vue 3で実際に実装した場合の例として、今回は「PokeAPI」を使ったサンプルコードを載せておきます。

またここのリポジトリもVue 3の機能がほぼすべて盛り込まれており、かなり参考になります。

もっとVue 3の理解を深めたい

今の所いざ業務などで本格的に使うようになったときに備えて、以下に最低触れておこうと考えています。

Design Patterns for Vue.js

Vue Test Utilsのメンテナーであり、Vue Testing Handbookの作者のLachlan Miller氏の本。

Vue JS 3: The Composition API

同じくLachlan Miller氏のUdemyコース。
今回の記事では触れませんでしたが、TeleportSuspense機能の知見がまだまだ甘いので、ここでキャッチアップしておこうと思っています。

その他Nuxt.jsのバージョン3やVuexバージョン5も今後広まっていくと思うので、リリースされたタイミングでしっかりキャッチアップしておこうと思っています。(Githubの公式リポジトリにも貢献していきたかったり)

26
36
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?