💭

Vue.jsのサンプルコードはなぜ使い物にならないのか?Vue 2と3の記法のちがいについて。

2022/11/16に公開

Vueを始めて困ること

Vue.jsを使用して悩むことの一つは、わからないことがあって調べようとするときにコードサンプルとして見つかるものがバラバラで統一されていないことでした。

ある場合は

<script>
export default {
  data() {
    return {
      title: 'HOME PAGE'
    }
  }
}
</script>

のように書かれています。同じようなことをやっているであろう別のコードはこうなっています。

<script>
export default {
  setup() {
    return {
      title: 'HOME PAGE',
    }
  }
}
</script>

あるいはこんなのもあります。

<script setup>
    const title = 'HOME PAGE';
</script>

どのコードサンプルをどう応用したらいいかわからなくなります。この混乱にはVueが辿ってきたベストプラクティスの変遷が関係しています。

Options API (Vue 2)

一番上の書き方のコードが、2022年時点で検索して最もたくさん見つかるものです。これは安定して使われてきたVue 2の書き方ですが、Vue 3でも使用可能で後述するComposition APIを使用するVue 3でも使用できるものです。この後方互換性が混乱を引き起こす原因ともなっています。

Options APIでは基本の書き方として、使用するデータをdata()で定義します。例えばこのようにです。

<template>
  <section>
    <div>{{ description }}</div>
  </section>
</template>

<script>
export default {
  data() {
    return {
      description: 'こんにちはOptions API'
    }
  }
}
</script>

<style scoped>
div {
  font-size: 2rem;
  font-weight: bold;
}
</style>

data()からreturnすることで、それを<template>内で使用することができるようになります。

Options APIの問題

このシンプルなコードではわかりにくいですが、コードが長くなり他のVueの昨日も盛り込んでいくと、この記法には問題があることがわかりました。ロジックを組み込んでいくと、関係する処理を書く場所がコード内でバラバラになってしまい関連性がわかりにくくなるのです。

そのためにVue 3では別のアプローチとしてComposition APIというものが導入されました。

Vue 3 (Composition API)

Vue 3になって記法が大きく変わりました。上記の同じことをするコードはこのようになります。

<script>
export default {
  setup() {
    const description = 'こんにちはComposition API';
    return {
      description,
    }
  }
}
</script>

<template>
  <section>
    <div>{{ description }}</div>
  </section>
</template>

<style scoped>
div {
  font-size: 2rem;
  font-weight: bold;
}
</style>

新しくsetup()を使用して定義することになりました。この短いサンプルではわかりにくいですが、Vueの他の記法は関係するものが比較的まとまりやすい形になりました。これが同じようなコードサンプルでも、書き方が微妙に違う理由です。

しかし初学者にはさらにハードルを高めるVueの進化があります。

Vue 3.2 <script setup>

最新の書き方でベストプラクティスとされるようになったのは以下のような書き方です。

<script setup>
    const description = 'こんにちはComposition API script setup';
</script>

<template>
  <section>
    <div>{{ description }}</div>
  </section>
</template>

<style scoped>
div {
  font-size: 2rem;
  font-weight: bold;
}
</style>

確かにコードの部分が非常にシンプルになりました。よく見ると、<script>タグのところが、<script setup>という書き方に変わっています。これが2022年11月現在の推奨される書き方です。

しかし他の2つの記法も現在のVueで使用できます。そのためコードサンプルを検索すると、これらがランダムに見つかるため混乱が生じます。

見分け方

それでコードサンプルを検索した際に、自分が見つけたコードがどの世代のものであるかを見極めることが大切です。

Options APIの場合

<script>タグの中に、data()がある場合はOptions APIの記法です。Vue 2での書き方ですが、Vue 3を使用していたもこの書き方が使えます。

普通のComposition APIの場合

<script>タグの中に、setup()がある場合はComposition APIの記法です。Vue 3での書き方ですのでVueのバージョンが2系統だとエラーになります。Nuxt 2の場合もエラーになりますので注意が必要です。

スペルミスとかがないのにこんなエラーが出ていたら、Vue 2でComposition APIを使用しようとしていないかを疑ってみましょう。

[Vue warn]: Property or method "title" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.

Composition API script setupの場合

こう呼ぶのが正しいのか、単にComposition APIとだけ言われて書かれている場合もあります。普通のComposition APIと大きく書き方が違うので別の名前をつけてくれたほうが混乱しなかったかと個人的には思います。

上記で書いた「普通の」あるいは「初代」Composition APIとの違いは<script>が<script setup>となっていることです。そしてその中のコードが非常に簡潔になっていることです。

まとめ

Vue 2から3になり設計思想ごと大きく変えたことで、バージョン移行のコストの高さに絶望して多くのVue開発者がReactに流れたとの噂があります。真偽はともかくとしてVue 2時代からがっつりと開発に使用してきたシステムからすると文句の一つも言いたくなるのもよく理解できます。しかし確実に進化し、シンプルでわかりやすいところに落ち着いてきたとも言えるので、今がVueの学び時とも言えるかもしれません。

Vueで何かやりたいと思う際に、検索した結果のソースコードがあまりにもバラけていることに本当に戸惑いました。遠回りをしながらなぜエラーになるのかを試行錯誤を重ねることになりました。しかしこの仕組がわかると、ネット上に散見するVueのサンプルコードを活用できるようになるはずです。

Discussion