【Vue.js】Vue + typescript について (vue-class-component, vue-property-decorator って何?)

はじめに

会社にてvue.jsを使って開発をしているので、vue.jsを用いて開発を行なっています。
コードを読んで似たような処理を行う箇所を探してやっている処理を推論して参考にして書くことを繰り返していても理解は深まらないので、vue.jsってそもそもなんなの、ってところからvueの書き方色々を調べてみてまとめようかと思います。
いろんな記事を読んで、そこから自分が知りたかったことを抜粋してまとめてる感じです。

Vue.jsについて

Vue.jsとは

Vue.jsとは、javascriptのフレームワークの内の一つ。他のjavascriptのフレームワークで代表的なものには、ReactAngularなどがある。

javascriptのライブラリとして有名なものにjQueryがあったが、SPD(Single Page Application)を用いたwebサイトの増加等、フロントエンド側に開発主体が移りつつある中で、DOMの操作を全て手動で行わなければいけないという面倒臭さがあり、それに対応するように新たな上述のフレームワーク群が登場した。

そうしたフレームワークの中でも、Vue.jsは低い学習コストで開発が始められるのが特徴。AngularやReactと比較してフレームワークの規模が小さい分、覚えることも少ない。JavaScriptやjQueryの基礎知識があれば数時間の学習で開発を開始することができる。(らしい)

Vue.jsと他のフレームワークとの比較

React

ReactはFacebookが開発を主導している、JavaScriptフレームワーク。

  • viewに関する機能のみを提供 : 自由なライブラリの選定が可能
  • JSX記法 : JavaScriptで記述することができ、導入・学習コストが高くない。
  • virtualDOM : 実際のDOMへの操作より高速・軽量に操作可能な仮想DOM
  • Vue.jsと違いReactの場合、データバインディングがデータから画面(HTML)に行く片方向のみ。
  • Angular、Vue.jsと比較すると、Reactは日本語での記事や書籍が少ない。

Angular(AngularJS)

AngularはGoogleと個人や企業のコミュニティから開発されたJavaScriptフレームワーク。

  • フルスタックフレームワーク : 技術選定や各ライブラリの相性問題に悩まさない一方、柔軟性もない
  • typescriptが前提 : フレームワーク以外に、typescriptの学習コストもかかる
  • 双方向データバインディングの実現

vue.js

Evan Youという個人が開発したフレームワーク。
vueはReact, Angularよりも後発で、両者のいいとこ取りをしている感じ。

  • 低い学習コスト : AngularやReactと比較してフレームワークの規模が小さい分、覚えることも少ない。JavaScriptやjQueryの基礎知識があれば数時間の学習で開発を開始することができる。(らしい)
  • Virtual DOMを採用
  • 双方向データバインディングも採用
  • HTTP通信やルーティングなどは別ライブラリと組み合わせて実現する方式

Vue + typescriptの書き方

さて、では本題。
Vueにtypescriptを導入する場合、Vue.extendvue-class-componentを使う二つの書き方ができるらしい。

vue-class-componentってなに?

TypeScript(.tsファイル)でコンポーネントが書けるようになる。
Componentデコレータをつけて、Vueを継承したクラスとして書く。
例えば、空のコンポーネントはこんなかんじらしい。

import Vue from 'vue'
import Component from 'vue-class-component'

@Component
class MyComponent extends Vue{
}

書き方

  • data : クラスの変数として書く
  • computed (算出プロパティ) : getterとして書く
  • methods : 普通にメソッドとして書く
  • ライフサイクルフック : 名前を合わせてメソッドとして書く

詳しくはvue-class-componentを見れば大体わかるらしい。ソースコード読むの大事。

vue-property-decoratorってなに?

vue-class-componentをさらに使いやすくするためのもの。
vue-class-componentではpropsなどはComponentデコレータの中に書いていく。

import Vue from 'vue'
import Component from 'vue-class-component'

@Component({
  props: {
    hoge: String
  }
})
class MyComponent extends Vue {

}

vue-property-decoratorを使うと、デコレータを使って書ける。

import Vue from 'vue'
import Component from 'vue-class-component'
import { Prop } from 'vue-property-decorator';

@Component
class MyComponent extends Vue {

  @Prop({ type: String })
  hoge: string

}

クラスメンバとしてかけるため、嬉しい。
詳しくはvue-property-decorator。ちゃんとソースコード読まねば。

vue.extend vue-class-componentの書き方比較

例えばこんなVue.jsコードがある場合、

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>{{ saySomething() }}</p>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    msg: {
      type: String
    },
  },
  methods: {
    saySomething() {
      const something = "something";
      return something;
    },
  },
};
</script>

Vue.extendを使うとこうなり,

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>{{ saySomething() }}</p>
  </div>
</template>

<script lang="ts">
import Vue from "vue";

export default Vue.extend({
  name: "HelloWorld",
  props: {
    msg: {
      type: String
    },
  },
  methods: {
    saySomething(): string {
      const something = "something";
      return something;
    },
  },
});

vue-class-componentを使うとこうなる

<template>
  <div class="hello">
    <h1>{{ messsag }}</h1>
    <p>{{ saySomething() }}</p>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";

@Component
export default class HelloWorld extends Vue {
  @Prop() private msg!: string;

  saySomething(): string {
    const something = "something";
    return something;
  }
}
</script>

vue.extendを用いる記法は、従来のvue記法と変わらずわかりやすい。
vue-class-componentの書き方は、コード記述が全くと言っていいほど変わっている。

でも、何が何に対応しているとかちゃんとわかれば、大丈夫そう。
勉強頑張ります。

参考記事

Vue.js概要、フレームワーク比較

Vue.js + typescriptの記法に関して