【vue2 / vue3 】書き方の変更点まとめ(TypeScript)

##TypeScriptで書く、vue2とvue3の変更点
詳しい説明は割愛した書き方の変更点の備忘録です。
※他の変更点等もあると思いますが、現時点で自分が使ったもののみを挙げています。
ここにない情報やご指摘などぜひ教えてください！


まずは同じコードのvue2とvue3の比較です。
↓表示させたい画面はこちら
![ezgif-4-da28fb6412.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2102695/6ece449a-85e9-796c-c50b-cfd6c7c454f7.gif)

インプットタグに入力した文字をv-modelで表示させるシンプルな挙動です。
クリアボタンを押下すると入力した文字が消えます。

##vue2での書き方
```typescript:vue2
<template>
  <div>
    <h3>名前を入力してください</h3>
    <span>名前：</span>
    <input type="text" v-model="name" />
    <br /><br />
    <div>
      私の名前は「{{ name }}」です。
      <button type="button" v-on:click="clear">クリア</button>
    </div>
  </div>
</template>

<script lang="ts">
// vue-property-decoratorをインポート
import { Component, Vue } from "vue-property-decorator";

@Component
// コンポーネントをクラスで定義し、vueのコンポーネントの性質を継承
export default class Sample extends Vue {
  // v-modelで双方向データバインディングをするための変数を定義
  private name = "";

  /**
   * クリアボタンを押すと呼ばれる
   */
  clear(): void {
    this.name = "";
  }
}
</script>

```
##vue3での書き方
```typescript:vue3
<template>
  <div>
    <h3>名前を入力してください</h3>
    <span>名前：</span>
    <input type="text" v-model="name" />
    <br /><br />
    <div>
      私の名前は「　{{ name }}」です。
      <button type="button" v-on:click="clear">クリア</button>
    </div>
  </div>
</template>

<script lang="ts">
// defineComponentとref(使う場合のみ)をインポート
import { defineComponent, ref } from "vue";

// defineComponent関数を使う
export default defineComponent({
  // setup関数の中で処理を定義
  setup() {
    // constかletで宣言
    // refメソッドかreactiveメソッドを使って値を監視
    let name = ref("");

    /**
     * クリアボタンを押すと呼ばれる
     */
    const clear = () => {
      // 「this.変数名」が使えなくなり、「変数名.value」と書く
      name.value = "";
    };

    // setup関数の戻り値は<template>内で参照が可能になる
    return {
      name,
      clear,
    };
  },
});
</script>
```
では、一つずつ違いを見ていきます。

##インポートするものの違い
● vue2 
``` import { Component, Vue } from "vue-property-decorator";
```

● vue3
```import { defineComponent, ref } from "vue";
```
refは使う場合のみです。

##コンポーネントの定義方法
● vue2 
```@Component
export default class クラス名 extends Vue {}
```
● vue3
```export default defineComponent({
 setup() {},
});
```
##フィールド変数の定義方法
● vue2 
```private 変数名 = 値
```
● vue3
```const(もしくはlet) 変数名 = ref(値)
```
refメソッドの他にreactiveメソッドもありますが、
refメソッドはプリミティブ(string,number,booleanなど)に使い、
reactiveメソッドはオブジェクトに使用すると良さそうです。

＊ data()を用いるとデフォルトで変数がリアクティブになりますが、
 setup()内で宣言された変数は変更されないため、refメソッドかreactiveメソッドを使ってリアクティブにしています。

また、vue3でprivateを使って宣言できる方法をご存知の方がいたらぜひ教えていただきたいです。

##メソッドの定義方法

● vue2 
```メソッド名():データ型 {}
```
今回の例：
clear(): void { this.name = ""; }


● vue3
```const 関数を定義
```
今回の例：
const clear = () => {name.value = ""; };


これまでmethodsの中で定義していたメソッドを、関数として作るようになりました。

＊ setup()内では「　this.変数名　」を使って参照ができなくなりました。
refを使った場合は「 変数名.value 」で参照すると良さそうです。

##return
● vue2 
なし

● vue3
```return{setup()内で定義したプロパティ名}
```
setup()内の最後にreturnで戻り値を返します。

今回の例：
 return {　name,　clear,　};

#ストアのアクセス方法
こちらは新しいファイルで書いていきます。
↓表示させたい画面はこちら
![画面の挙動2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2102695/ad9f97ec-98b9-20e3-9163-624e4943955e.gif)

ストアに保存したスポーツ情報を取得し、ボタンを押下すると表示されます。

↓ストアに保存した情報はこちら
![vuex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2102695/e6b2e192-053f-9d81-4008-d58683fe55e8.png)
私はvue2と同じ書き方で使用していますが、もし変更点などあれば教えてください。


##vue2での書き方
```typescript:vue2
<template>
  <div>
    <h3>スポーツ一覧</h3>
    <div v-for="sport of this.sports" v-bind:key="sport.name">
      {{ sport.name }}
    </div>
    <button type="button" v-on:click="showSports">表示させる</button>
  </div>
</template>

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

@Component
export default class Sports extends Vue {
  // ストアから取ってきた情報を格納する配列
  private sports = [];

  /**
   * スポーツ一覧を表示させる.
   */
  showSports(): void {
    // ストアのgetterから呼んできたスポーツ一覧を格納
    this.sports = this.$store.getters.getSports;
    // 配列の長さ分だけ回す
    for (let i = 0; i < this.sports.length; i++) {
      return this.sports[i];
    }
  }
}
</script>
```
##vue3での書き方
```typescript:vue3
<template>
  <div>
    <h3>スポーツ一覧</h3>
    <div v-for="sport of this.sports" v-bind:key="sport.name">
      {{ sport.name }}
    </div>
    <button type="button" v-on:click="showSports">表示させる</button>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref } from "vue";
import { useStore } from "vuex";

export default defineComponent({
  setup() {
    // setup()内でストアにアクセスする際は、useStore関数を呼び出す
    const store = useStore();
    // ストアから取ってきた情報を格納する配列
    let sports = ref([]);

    /**
     * スポーツ一覧を表示させる.
     */
    const showSports = () => {
      // this.$storeが使えなくなり、store.〇〇で呼ぶ
      sports.value = store.getters.getSports;
      for (let i = 0; i < sports.value.length; i++) {
        return sports.value[i];
      }
    };
    return {
      showSports,
      sports,
    };
  },
});
</script>
```

では改めてストアのアクセス方法の変更点です。

● vue2 
```this.$store.取ってきたいもの
```
今回の例：
this.$store.getters.getSports

● vue3
```const store = useStore();
sotre.取ってきたいもの
```
今回の例：
 const store = useStore();
    <略>
    const showSports = () => {
      sports.value = store.getters.getSports;
      <略>

useStore関数のインポート文も忘れずに。
routeを使うときも同じ感じで書いていくようです。

##その他
こちらはまだ自分では使っていないので検証できていないですが、

・created()がなくなり、setup()内に処理を直書きするだけでcreatedと同じ役割を果たす
・ストアでない普通のvueファイルにgetterを書く際はcomputedを使用する？

この２点も従来と違うようで気になります。
まだ自分自身分かっていないので、このあたりは開発しながら確かめていきたいと思います。

##終わりに
自分で調べてコードを書きながらまとめてみたので、違う部分もあるかもしれません。
ご指摘等あればぜひ教えていただきたいです！
Composition APIの詳しい説明などは他の方のが分かりやすいと思うので、こちらでは割愛いたしました。
最後までお読みいただきありがとうございました！

####参考文献
・https://devsakaso.com/vue-js-composition-api-basics/
・https://code-database.com/knowledges/65
・https://blog.asial.co.jp/1656
・https://zenn.dev/azukiazusa/articles/676d88675e4e74
・https://edge-labo.com/vue3-composition-api/#toc6
・https://kobatech-blog.com/vue-composition-api-ref-reactive/