初めてのフロントエンドとして「Vue.ts」を触ってみる

## 概要
今までRuby、Railsしかきちんと扱ったことはなかったのですが、この度業務でVue.js + TypeScriptを使わせてもらえることになったので、どんなものかと触ってみることにしました。
同じように初めてのフロントエンドとしてVue.jsとTypeScriptを扱う方の参考になれば幸いです。

## 参考
[vue.js + typescript = vue.ts ことはじめ](https://qiita.com/nrslib/items/be90cc19fa3122266fd7)
上記の記事が大変参考になりました。

## Vue.tsのプロジェクトを作成しよう
早速Vueをインストールして、`vue create アプリ名`でプロジェクトの作成を行ったのですが、デフォルトの設定のまま作成してしまうと、TypeScriptを使えません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624406/94a67377-7318-b19f-535f-5a575bf6915c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624406/5f86fd69-f9e9-f0e1-eb4d-2f578f658bf0.png)

`Default`ではなく、`Manually select features` を選択して、TypeScriptの欄にチェックを入れて作成しましょう！

## コンポーネントを作ってみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624406/c866ef7c-abd2-00ef-9b58-f5e175d5f595.png)

プロジェクトのディレクトリ構成はこんな感じです。

手始めに`Test.vue`というセンスのかけらもない名前のコンポーネントを作成してみます。

### コンポーネントとは？

コンポーネントとはボタンなどの小さなシステムのことを指します。このコンポーネントを多く組み合わせることで一つの大きなシステムを構築します。
srcディレクトリの配下にあるcomponentsディレクトリにvueファイルとして作成していきます。

```src/components/Test.vue
<template>
    <button @click="onClick">テストボタン</button>
</template>

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

    @Component
    export default class Test extends Vue{

      private count = 0;

      @Prop()
      public test?: string;

      @Emit()
      public click(count: number){
      }

      public onClick(){
        this.count++;
        alert("テストします");
        this.click(this.count);
      }
    }
</script>

```

上記のようなボタンコンポーネントを作成し

```src/App.vue
<template>
    <div class="home">
      <p>テスト{{count}}回目</p>
      <p>{{testText}}</p>
      <p>
        <Test :test="testText" @click="onTestClick"></Test>
      </p>
    </div>
</template>

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

    @Component({
        components: {
            Test,
    },
    })

    export default class Home extends Vue {
      private count = 0;
      public testText = "下のボタンを押してください";

      public onTestClick(count: number){
        this.count = count;
      }
    }
</script>
```

`App.vue`ファイルを介して表示させます。

まず、vueファイルの基本的な構成として、`template`と`script`に分かれており、`script`でロジックを記述し、それを`template`に引き渡して表示させるという形になっています。

```
    import Test from "@/components/Test.vue";

    @Component({
        components: {
            Test,
    },
    })
```

上記の箇所で、`Test.vue`で作成したコンポーネントを`App.vue`に引っ張ってきています。



```
      @Prop()
      public test?: string;

      @Emit()
      public click(count: number){
      }
```


`Props`では親コンポーネントから値を受け取ることができます。
この例では親コンポーネントである`App.vue`から`testText = "下のボタンを押してください"` というデータを受け取っています。これにより、同じPropsを用いるすべての子コンポーネントの変更を`App.vue`から行うことができるようになります。

`Emit`では逆に子コンポーネントから親コンポーネントに値を引き渡すことができます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624406/eb161be2-fa5e-f5b1-1279-dad37e9ae155.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624406/dbc11551-d241-c07c-5c84-e417467a122b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624406/ac473a02-4da8-6881-a11d-73e7984b5ee3.png)



このようにクリック回数をカウントするボタンが作成できました。

## 終わりに

Vue.tsについてほんの少しだけ触ることができました。他のフロントエンドを触ったことがないため比較ができませんが、型定義など保守性の高いツールとのことで、今後また簡単なものを作成し、実感できればなと思っております。