Vue.jsでTypeScriptを使う(デコレーターとVue.extendの2パターン)

はじめに

前回はとりあえずTypeScriptを使ってみました。

今回はVue.jsを使いながらTS自体の書き方だったりをしっかりと把握しながら理解を深めていきたいと思います。

※5/29追記

Vue.extendなら使えそうだったので試しに少しだけ触ってみました。デコレーターは書き方だいぶ変わりますね。。。

TypeScriptをとりあえず使ってみた(React+TSも試した)

✅ゴール

・TypeScriptの理解を深める

✅参考教材

📚プログラミングTypeScript ―スケールするJavaScriptアプリケーション開発

ソースコード

💻Vuexによる状態管理を含む最高に快適な Vue.js + TypeScript の開発環境を目指す話

Vue.jsでTypeScript使うなら押さえておきたい記事!!

💻TypeScript のサポート(公式)

TypeScriptの基礎おさらい

まずはTSの基礎のおさらい。

参考:さらっとTypeScript入門

✅環境構築

①インストール

npm install -g typescript
tsc -v
>> version 3.8.3

②プロジェクト作成/初期設定

mkdir ts_test
cd ts_test
tsc --init

③test.tsの作成

let message = 'こんにちは!';
console.log(message);

④コンパイル

tsc test.ts

⑤ビルド(自動)

tsc -b --watch

✅書き方

①型の基本

変数名の前に:(コロン)を付けて型名(アノテーション)を付ける

let message :string = 'こんにちは';

②配列

型名の後にブラケット([])を付ける

let numbers1: number[] = [ 1, 2, 3 ];
let numbers2: Array<number> = [ 1, 2, 3 ]; // 別パターン。出力は同じ
let list: [number, string, number] = [ // 複数の型の指定
    1, 'hoge', 2
];

③オブジェクト

let user: object = {
  id: 1,
  name: '山田太郎',
  age: 28
};
~~オブジェクトの中の型推論にはインタフェースという機能を。
interface User {
  id: number
  name: string
  age: number
};
~~typeを使用する場合。(出力は同じ。)
type User = {
  id: number
  name: string
  age: number
};

④複数の型指定

let message : string | null = 'こんにちは';
message = null; // nullも入れることができる

⑤関数

function sum(num1: number, num2: number): string {
const sum: number = num1 + num2;
return `${num1}+${num2}は、${sum}です。`;
}

sum(3,5) // 3+5は、8です。

⑥クラス

class Calc {
private num1: number;
private num2: number;
constructor (num1: number, num2: number) {
this.num1 = num1;
this.num2 = num2;
}

public sum(): string {
const sum: number = this.num1 + this.num2;
return `${this.num1}+${this.num2}は、${sum}です。`;
}
}

const calc = new Calc(5,6);
calc.sum(); // 5+6は、11です。

※リアルタイムにコンパイルしてくれるので、tsc -b –watchは非常に便利!!

他にも項目がありますが、一旦チュートリアルなりをやりながら更に理解を深めていこうと思います。

Vue.jsでTypeScriptを使ってみる(デコレータ編)

※デコレータを使うパターンとVue.extendを使う2パターンがある。以下は諸々デコレータを使ったパターンです。

参考:

TypeScript + Vue.js の始め方 記法に関してわかりやすい
TypeScriptでVue.jsを書く – Vue CLIを使った開発のポイントを紹介(※テスト前までの内容) 記法などこちらも説明がわかりやすい
vue.js + typescript = vue.ts ことはじめ(プロパティとバインディングの部分まで) ※一通り丁寧に説明されている。ただ、これ通りにやってもRouterの描画はデフォルトで表示されない。。。
VueをTypeScriptで記述する方法について解説 一通りのコンポーネントの記述がされているゲームを作成。ミニマムでわかりやすい 

メリット
①JavaScriptにはない静的型付けを行うことでエラーハンドリングが行いやすい。
②クラスベースのオブジェクト指向での開発ができる。

👍Vueをクラス構文で開発しながら実装中にエラーハンドリングをすることができる。
※通常の記法で静的型付けをすることも可能。

1.環境構築

①プロジェクト作成

$ vue create vuets

Vue CLI v3.8.2
┌───────────────────────────┐
│  Update available: 4.3.1  │
└───────────────────────────┘
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, TS, Linter
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
? Pick a linter / formatter config: TSLint
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)Lint on save
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In package.json
? Save this as a preset for future projects? No

②起動

cd <プロジェクト名>
npm run serve

③ビルド

npm run build

distディレクトリ内にバンドルファイル(組み合わせたファイル)が出力されるのでこれをデプロイすればOK。

2.コンポーネントの作成(JS/TSでの比較)

・JavaScriptの記述

<script>
export default {
  name: 'About',
  props: ['foo'],
  data() {
    return {
      id: 0,
    }
  },
  methods: {
    myMethod(id) {
      // 処理
    },
    bar() {
      this.$emit('barEvent', 'bar')
    }
  },
  computed: {
    myCalc() {
      // 処理
    }
  },
  mounted() {
    return 'foo';
  },
}
</script>

・TypeScriptの記述

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

@Component
export default class About extends Vue {
  id: number = 0
  @Prop() foo!: string; // !は必ず設定、?は必ず設定する必要はないことを示す。
  @Emit('barEvent')
  bar(val: string): void {}
  bazz() {
    this.bar('bar')
  }  
  myMethod(id: number): void {
    // 処理
  }
  get myCalc(): number {
    // 処理
  }
  set myCalc(): void {
    // 処理
  }
  mounted(): string {
    return 'mounted';
  }
}
</script>

※Vueプロジェクトを作成する際にpresetでTypeScriptを選択すればOK(公式サポート済)。scriptタグ部分にlang=”ts”と追記される。

※voidはundefinedを返してくれる演算子。戻り値がない場合などに利用。

✅コンポーネントをエクスポートする際の記述方法

TSはクラス記法を一般的に用いる。

①クラス形式で定義したコンポーネントの上部に@Component
②クラスがVUえのコンポーネントの性質を継承するためにextends Vueの記載をする。

※@Componentは、vue-property-decoratorを利用して、直下で宣言されているクラスがVueコンポーネントであることを示すアノテーション。

・dataプロパティ:クラスのプロパティで記載。
・methodプロパティ:クラスのメソッドで記載。
・computedプロパティ:get/setアクセサになる。
・props,$emit:vue-property-decoratorで用意されているデコレータ@props,@emitアノテーションを変数の上部に記載して定義する。
・ライフサイクルフック(mountedなど):クラスのメソッドで記載。
・監視プロパティ:@Watchアノテーションを利用。

✅vue-property-decorator

VueをTS特有のクラス構文で書くためのツール

props,emit,watchなどの定義はアノテーション(@Component)としてサポートされている。

※Vue CLIでプロジェクトを作成する時に、「Use class-style component syntax」をyesと選ぶとインストール

※公式が提供しているvuejs/vue-class-component(こちらもクラス構文でコンポーネントを記述可能にする)にいくつかデコレーターを増やしたようなイメージらしい。公式サポートのライブラリ。

✅shims-tsx.d.ts、shims-vue.d.ts

.vueファイルをTypeScriptで利用可能とするためのファイル。srcディレクトリ内に入れておく。

✅tsconfig.json

TypeScriptのコンパイル時に使われる設定ファイル

Vue.jsでTypeScriptを使ってみる(Vue.extend編)

💻[Vue+TypeScript] Vue.extend で Vue らしさを保ちつつ TypeScript で書くときの型宣言についてまとめた
💻【Nuxt.js】TypeScript基礎編:Vue.extendでシンプルなコードを書こう
💻Vue.js in TypeScript で型定義をどこに書けばいいか

※5/29追記

なんとなくTSの理解が進んできて、Vue.extendの方が使いやすそうだと感じていたので試してみました。

$ vue create vue-extend-ts

Vue CLI v3.8.2
┌───────────────────────────┐
│ Update available: 4.4.1 │
└───────────────────────────┘
? Please pick a preset: Manually select features
? Check the features needed for your project: TS
? Use class-style component syntax? No
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? No
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? No

起動と確認

npm run serve

諸々そぎ落として以下のようにApp.vueを編集。

<template>
  <div id="app">
    {{ value }}
  </div>
</template>

<script lang="ts">
import Vue from 'vue';
// typeの場合
export type DataType = {
  value: string
}
// interfaceの場合(※書き方がtypeと異なる)
export interface DataType {
  value: string
}
export default Vue.extend({
  // コンポーネント・ページ自体にクラスを付与
  name: 'App',
  data(): DataType {
    return {
      value: "Hello,Vue+TypeScript"
    }
  }
});
</script>

確認

🙄typeとinterfaceで書き方異なるのが謎。また、exportも端折れる。ここら辺は公式見ながらもうちょい解読していこう。

躓いた点

✅VSCodeでコマンドが実行されない。(tscコマンドが実行できなかった。)

起因:PowerShellのポリシー設定

解決策:PowerShellを管理者で実行して以下コマンドでポリシーを変更。

Set-ExecutionPolicy RemoteSigned

参考:PowerShell のスクリプトが実行できない場合の対処方法

✅Vue Routerが読み込まれない

起因:不明

解決策:別途インストールして設定する。

参考:Vue.js で Router 使ってみよう RouterはTSらしい記述にはなっていないのが気になるがとりあえず実装できた。

おわりに

Vue.jsでTypeScriptを使う方法はなんとなくわかってきた。

あとはTypeScript自体の勉強をオライリー本でして、自身のVue.jsプロジェクトをTypeScriptに変換していってみよう。

※5/29追記

やっとVue.jsでTSを使う方法がしっかりと理解できて来た。が、わざわざ使う魅力をあまり感じないのも事実。。。

こればっかりは現場なり入ると必要性に問われるのかな??

とりあえずデコレーター使わずにVue.extend使ったほうが個人的には手軽。デコレーター使うなら今後要勉強。

参考になる記事まとめ

✅基礎

さらっとTypeScript入門 ⭐これ参考にグローバルにTSインストール。tscをVSCodeで使えるようにした。
TypeScriptチュートリアル① -環境構築編-
TypeScriptの型入門 ⭐これで充分というくらいボリューミー
TypeScriptの型演習 ⭐上記の問題集
TypeScriptによるデコレータの基礎と実践 かなり発展的な内容まで。ゆくゆくチェックする。
JavaScript の デコレータ の使い方 TSで初めて知った知識はJSでもある機能なのか??調べないと本質理解できない気がする。。。そして、持っている書籍がES6なのでここに記載されていないような追加項目も多々。デコレータもそのうちの1つ。

✅Vue.js
Vuexによる状態管理を含む最高に快適な Vue.js + TypeScript の開発環境を目指す話 ⭐⭐マストチェック!!
TypeScript のサポート(公式)
Nuxt TypeScript(公式)
VueをTypeScriptで記述する方法について解説 ⭐メリットの説明がわかりやすい。
Vue.js+JSX基本文法最速入門 Vue.jsでもJSX使えるの初めて知った。
はじめてのvue-property-decorator (nuxtにも対応 Vue.jsでTS使うならデフォルトで記載されているので理解あったほうが良さげ。
デコレータ使わない Vue.js + TypeScript で進んだ「LINEのお年玉」キャンペーン 一方で、デコレータを使わないことも可能みたい。
【Vue.js】プロパティ(props)の使用方法 デコレータで調べると、タイトルにTSの表記がなくてもTSに関して解説されている記事が見つかる。
Nuxt × TypeScript でTodoListとユーザ認証を実装してFirebase Hostingにデプロイ [Tutorial – Part 1/5 – 環境構築とHelloWorld]
vue.js + typescript = vue.ts ことはじめ ⭐とりあえず試してみるにはもってこい。一通り丁寧に説明されている。ただ、これ通りにやってもRouterの描画はデフォルトで表示されない。。。
TypeScript + Vue.js の始め方 ⭐記法に関してわかりやすい
TypeScriptでVue.jsを書く – Vue CLIを使った開発のポイントを紹介 ⭐記法などこちらも説明がわかりやすい
vue-routerを無理やりTypeScriptで型安全にする そもそもVueRouterは型安全じゃないらしく、拡張が必要らしい。
VueをTypeScriptで記述する方法について解説 ⭐一通りのコンポーネントの記述がされているゲームを作成。ミニマムでわかりやすい

✅Nuxt
【Nuxt.js】TypeScript基礎編:Vue.extendでシンプルなコードを書こう

✅React
React入門(TypeScript版)
React.js + TypeScript でTodoアプリを作ってみる
【React知見】条件分岐(IF文)とそのネスト JSXに関する知見。
React公式チュートリアルをTypeScriptでやる

✅書籍
実践TypeScript ~ BFFとNext.js&Nuxt.jsの型定義

コメントを残す