💻

Vue3のススメ

2021/12/15に公開

この記事は、ユアマイスター AdventCalendar2021 の15日目の記事です。

こんにちは佐々木です。
弊社ではVue2からVue3へのバージョンアップをしたのですがその時にVue3にしてよかった・・・!と思う瞬間があったため記事にしました。特に CompositionAPITeleport を使うことで可読性が上がり助けられたので私はVue3✖︎TypeScriptを推奨しています。現在Vue3化を検討している人の参考になれば嬉しいです!

※本記事はVue.js, Vue3の機能を網羅的に解説した記事ではないので予めご了承ください。

本記事の対象者

  • Vue3にしたいけどどう変更されたのかよくわからない人
  • Vue3にすることでどう嬉しいのかよくわからない人

CompositionAPIのおかげで統一感が生まれ可読性が上がった

Vue2時代はdata(), created(), methods(), computed()が階層ごとに散らばっていました。そのせいでcreatedで実行しているメソッドはどこにあるのか、dataに宣言してある変数はどこで使われているのかなど何度もジャンプをしてソースコードを読まないといけませんでした。私はこの文法のせいで何度もソースコードないで迷子になることが多かったです。

CompositionAPIの導入のおかげで、setup関数内に使う変数・メソッドを一箇所にまとめることができるようになり可読性が上がりました。scriptタグ内を <script setup> と書くことで下記のように直接処理したいコードを書き始めることもできます。

CompositionAPI 公式リファレンス

<script lang="ts">
export default defineComponent({
    setup: () => {
    // コード
    }
})
</script><script setup lang="ts">
// コード
</script>

下記はOptionalAPIとCompositionAPIのコード比較です。

Vue2

App.vue
<script>
export default {
  data() {
    return {
      books: [],
      readBookCount: 0,
    }
  },
  created() {
    this.getBook()
  },
  methods: { 
    async getBook(){
    try {
      const response = await this.$axios.get('url')
      this.books = response.data.books
    }catch (error) {
      console.error(error)
    }
    },
  },
  computed: {
    countFinishedRead: function() {
      return this.books.filter(book => book.read)
    }
  },
}
</script>

Vue3

<script setup lang="ts">
import { ref } from 'vue'
import { useBooks } from '../composables/books.ts'
const { books } = useBooks()
const countFinishedRead = computed(() => {
  return books.filter((book) => book.read)
})
</script>
books.ts
import axios from 'axios'

type Book{
  id: string
  title: string
  author: string
  read: boolean
}

export const useBooks = () => {
  const books = ref<Book[]>([])
  const getBooks = async() => {
    const response = await axios.get('/url')
    books.value = response.data.books
  }
  return { books }
}

Teleportで好きな場所にコンポーネントを移動できる

Teleport はなにかというと「好きな場所へコンポーネントを表示する」ことのできる機能です。

特にモーダル表示の際に使いたい時に便利です。
Teleportを使わない場合のモーダル実装では、一つのHTMLファイルにモーダル用の要素を作成します。その際にモーダル要素を一番上のコンテンツとして表示するためにz-indexというcssのプロパティを使いますが、z-indexが何個もHTML生まれると出てきて欲しい文言が消えたりなど想定外ことが起きてしまうということがありました。
Teleportを使うことでz-indexによる要素の打ち消し合いを防止することができました。

App.vue
<template>
  <div id="modal" />
  <teleport to="#modal">
    <div class="overlay">
       <div class="box">
           これはモーダルです
       </div>
    </div>
  </teleport>
</template>

<style>
.overlay {
  display: grid
  position: fixed
  top: 0px;
  right: 0px;
  bottom: 0px;
  left: 0px;
  align-content: center;
  --tw-bg-opacity: .6;
  background-color: rgba(217, 217, 217, var(--tw-bg-opacity));
}

.box {
  margin-left: auto;
  margin-right: auto;
  background-color: var(--color-white);
  padding: 16px;
}
</style>

そのほかにも、Vue3からTypeScriptが対応可能になりました。
APIの処理をする際に型定義ができるためどんな値が返ってくるのかわかることができ安全に処理を書くことができ安心して開発をすることができています。

まとめると

  • CompositionAPIのおかげでソースコードを追っているときに迷子になることがなくなった
  • Teleportのおかげでz-index地獄から抜け出した
  • TypeScript対応のおかげで安全な開発が期待できるようになった

以上の理由からVue3をゴリ押しします。

Discussion