Vue.jsのプロジェクトでTypeScriptを使いたい

  • 32
    Like
  • 2
    Comment
More than 1 year has passed since last update.

はじめに

ここ最近、TypeScriptが注目を浴びているように思います。TypeScriptはJavaScriptの世界に「型」を導入し、またES6以降の文法をES5以下の文法で表現できるように変換してくれる有り難い存在です。しかしながらVue.jsのプロジェクトでTypeScriptを使うのはこれまで難しいことでありました。なぜなら、View ModelのコンストラクタがTypeScriptのクラス構文と相性が悪かったからです。

app.ts
class App {
    firstname: string;
    lastname: string;

    constructor(firstname: string, lastname: string) {
        this.firstname = firstname;
        this.lastname = lastname;
    }

    get fullname(): string {
        return `${this.firstname} ${this.lastname}`;
    }

    set fullname(fullname: string) {
        const [firstname, lastname] = fullname.split(" ");
        this.firstname = firstname;
        this.lastname = lastname;
    }

    greet() {
      console.log(`My name is ${this.fullname}.`);
    }
}

他のフレームワークないしライブラリならこのように書いてthisの型をはっきりさせることができます。Angular 2やReact、AureliaなどはTypeScriptを使うときクラス構文を使用するのが普通ですし、Backbone.jsやKnockoutJSでもTypeScriptを利用することは容易いことです。一方でVue.jsは以下のようにコンポーネントを定義します。この書き方はとてもわかりやすくて良いのですが、これをTypeScriptで書いたとしてもthisの型が何であるか、TypeScriptにとってはわからず、型の恩恵を受けることができません。

app.js
const App = Vue.extend({
  data: () => ({
    firstname: "",
    lastname: ""
  }),
  computed: {
    fullname: {
      get() { return `${this.firstname} ${this.lastname}` }
      set() {
        const [firstname, lastname] = fullname.split(" ");
        // thisがなんだかわからない
        this.firstname = firstname;
        this.lastname = lastname;
      }
    }
  },
  methods: {
    greet() {
      console.log(`My name is ${this.fullname}.`);
    }
  }
})

目的

  1. Vue.jsのコンストラクタにTypeScriptのクラス構文を利用してthisの型をはっきりとさせる。
  2. Vue.jsとTypeScriptを使って何かしらのアプリケーションを作成し、その有用性を確認する。

方法

はじめに

今回採用する方法はTypeScriptデコレータを使う方法です。Angular 2やAureliaで見慣れている人が多いと思います。Vueコンストラクタを継承して_initメソッドを呼び出す方法もありますが、それと比較して

  • プライベートなメソッドを呼び出さずに済む
  • 関心の分離ができる

といったメリットがあります。その一方デコレータを多用するためコンパイル後のコード量が増加します。
それから、ファイルのコンパイルにWebpackとts-loader、それからhtml-loaderを利用します。

ダウンロードするもの

Dependencies

  • Vue.js
  • vue-class-component

Dev Dependencies

  • TypeScript
  • Webpack
  • ts-loader
  • html-loader

作るもの

今日は12月4日、『新世紀エヴァンゲリオン』に登場するキャラクター「惣流・アスカ・ラングレー」の誕生日であります。したがって彼女の誕生日をお祝いするアプリケーションを作ろうと思います。
また、『ご注文はうさぎですか?』のチノちゃんも12月4日が誕生日だそうです。

型定義ファイルを用意する

DefinitelyTypedから必要な型定義ファイルをダウンロードしたり、自分で書いたりします。
vue.d.tsを割と最新のものに更新し、vue-router.d.tsをDefinitelyTypedに登録しました。ぜひお使いください。さらにvue-resource.d.tsもDefinitelyTypedに登録しました。

結果

ここに公開しました。
最近書き換えました。ダウンロードしてブラウザでpublic/index.htmlを開いてみてください。
せっかくなのでBootstrap 4を使ってみました。

考察

よくできたと思います。APIの変更などが多いので大変です。でもこれからも更新頑張ります。

終わりに

次のバージョンについて

過去のバージョン名は以下のとおりです。

  • Blade Runner
  • Cowboy Bebop
  • Dragon Ball
  • Evangelion

アルファベット順になっていることがわかります。したがって次期バージョンはおそらく『蒼穹のファフナー(Fafner in the Azure)』か『すべてがFになる(Subete ga F ni Naru)』が適当だと思っています。

参考にしたサイト・ページ

This post is the No.4 article of Vue.js Advent Calendar 2015