owned mediaウェブ制作に役立つコンテンツを発信中!

Vue.js 3系の導入とComposition APIを試してみる

最終更新日: Update!!
JavaScriptのフレームワークとしてよく使われているVue.jsですが、現在のバージョンは3系が新しいものになっているようです。ずっと2系をメインに使っていたのですが、そろそろ本格的に移行したほうが良いかなと思ったこともあり、改めてVue.jsの3系導入と、新機能のメインとなるComposition APIについても少し触れて備忘録として残しておきたいと思います。2系とは使える機能以外にも書き方などに少し差もあったりしますので、改めて覚えておきたいですね。   まずはVue.jsの3系本体をインストールしていきます。下記のコマンドで最新の安定版のバージョンが使えるようになります。
$ npm install vue@next
+ vue@3.2.31
  続けて、.vueの拡張子がついた単一コンポーネントファイルを扱う場合に、2系では「vue-template-compiler」のコンパイラを使っていましたが、3系では「@vue/compiler-sfc」というパッケージを使います。
$ npm install -D @vue/compiler-sfc
+ @vue/compiler-sfc@3.2.31
  必要に応じてその他のパッケージなどもインストールできたらVue.jsの3系を使う準備が整いました。また、CDNを使う方法もありますので、環境構築がなくとも手軽に利用できるのもいいですね。
<script src="https://unpkg.com/vue@next"></script>
   
Options APIでVue.js 2系との記述方法の違い
Vue.jsではいくつか書き方が存在しますが、よく使われているOptions APIを使った方法においては、2系と3系で少し異なるので注意が必要です。ここではv-modelを使った双方向のバインディングの下記サンプルを例に見ていきます。
<div id="app">
  <input type="text" v-model="formValue">
  <p>{{ displayValue }}</p>
</div>
  Vue.jsを使う際に、2系ではOptions APIの場合、下記のようにインスタンスを作成してからそれぞれのオプションに必要なデータや処理を記述していく方法になります。
// Options API(Vue 2.x)
const app = new Vue({
  el: '#app',
  data() {
    return {
      formValue: ''
    }
  },
  computed: {
    displayValue() {
      return this.formValue;
    }
  },
  mounted() {
    this.setValue();
  },
  methods: {
    setValue() {
      this.formValue = 'hello world';
    }
  }
});
  2系ではこれで問題なく動作しますが、3系になると下記のようなエラーが発生します。3系になると、従来のようにインスタンスを作成するのではなく「createApp」として関数ベースで作成していく形になります。
Uncaught TypeError: Vue is not a constructor
  では実際に3系でOptions APIを使う方法を見ていきます。まずはcreateAppの関数として作成し、引数の中に各種オプションを指定していきますが、基本的にこの部分に関しては2系と同じように記述できます。つまり、3系では従来型のOpitions APIもそのまま使えるようになっているようですね。ただし、最後のところで要素にマウントさせるのが必要になっているので注意しておきたいですね。
// Options API(Vue 3.x)
const app = Vue.createApp({
  data() {
    return {
      formValue: ''
    }
  },
  computed: {
    displayValue() {
      return this.formValue;
    }
  },
  mounted() {
    this.setValue();
  },
  methods: {
    setValue() {
      this.formValue = 'hello world';
    }
  }
});
app.mount('#app');
  このように少しの違いはあるものの、いろいろなライブラリやプラグインを導入していないケースにおいて切り替えるのはそこまで移行コストもなさそうですね。またその他にも3系で新たに導入された機能や仕様が変わる部分もあるようですので、詳しくは公式のドキュメントを参照してみてください。 (参考)Vue.js 2からの移行 https://v3.ja.vuejs.org/guide/migration/introduction.html    
Vue.jsの3系で使えるComposition API
では続いて、3系で使えるようになった「Composition API」というものについてみていきたいと思います。Options APIはとてもわかりやすい反面、データの種類や処理が増えてくる場合にコードが煩雑になるというような欠点もありました。そこで新たに登場するのがComposition APIです。Composition APIではコンポーネント間で関数などのロジックを再利用しやすくすることで、コンポーネント単位での依存度を少なくすることができる点がメリットのようです。実際のコードでOptions APIとの違いを比べてみます。先ほどのサンプルと同じ機能をComposition APIに置き換えると下記のようになります。
// Composition API
const app = Vue.createApp({
  setup() {
    const data = Vue.reactive({
      formValue: ''
       });
    const displayValue = Vue.computed(() => {
      return data.formValue;
      });
      const setValue = () => {
      data.formValue = 'hello world';
      }
      Vue.onMounted(() => {
      setValue();
    });
    return {
      data,
      displayValue,
      setValue
    }
  }
});
app.mount('#app');
  createAppの引数に、setUp()メソッドを指定し、その中で基本的な処理やデータを作っていきます。dataオプションにあった変数などは、reactive()メソッドの引数にデータを定義します。同じようなものにref()メソッドというのものあるようです。reactiveはオブジェクト型のデータを、refは文字列や数値などのプリミティブな値を扱うというのが使い分けとしてあるのですが、公式を見てもいまいち差がなさそうなところもあるようです。computedの処理は、computed()メソッドとして同じような形で値を返すような処理を定義します。methodsでの処理は、そのままsetup()メソッドの中の関数として定義します。   mountedなどのライフサイクルフックについては、mountedの場合にはonMounted()メソッドで実行するように、updatedにはonUpdated()メソッドなど、その他各種ライフサイクルフックに対応したフックが用意されているようですね。beforeCreateやcreatedで実行する処理はset()メソッド内でそのまま実行するようにします。そして最後に、setUp()メソッド内で定義した変数や処理を返すようにすることで値や処理を参照できるようになります。   ちなみに上記の場合では、v-modelで参照するデータ構造が変わるので下記のように修正する必要があります。
<div id="app">
  <input type="text" v-model="data.formValue">
  <p>{{ displayValue }}</p>
</div>
  Composition APIを使う方法ではその他にもOptions APIと異なる部分はありますが、詳しくはまた別記事でまとめてみたいと思います。  
  今回はVue.jsの3系の導入と、Composition APIを使った方法について触れてみました。ずっと2系ばかりを使っていたのですが、3系ではいろんな面で便利になっていることもあり積極的に導入していきたいですね。従来のOptions APIでも引き続き使えるようなので、少しずつ慣れてみようと思います。   (参考にさせて頂いたサイト) Vue.js v3 はじめに https://v3.ja.vuejs.org/guide/introduction.html
  • はてなブックマーク
  • Pocket
  • Linkedin
  • Feedly

この記事を書いた人

Twitter

sponserd

    keyword search

    recent posts

    • Twitter
    • Github
    contact usscroll to top
      • Facebook
      • Twitter
      • Github
      • Instagram