初学者がVue3+TypeScriptで開発を行っていく中で感じたこと・学んだこと（現在進行形）

#はじめに
###今回Vue3+TypeScriptを導入しようと思った理由
①Vue3がリリースされたのがもう1年前のことなのでVue2ではさすがに古いかなと感じたため
②TypeScriptの学習を開発する中で学びたかったから
③単純な探究心（使いたかった）

###Vue３の変更点
※**これは自分自身が開発(学習)を進めていく中で学んで感じた変更点になります**
①Composition APIの追加
defineComponent関数によってコンポーネントを作成
Vue2までのdata/methods/ライフサイクル等は全てsetup()関数内で宣言
⇢今の所、個人的に一番わかりやすいメリットかも、、、
とにかくコードが見やすくなったしわかりやすくなった！！！
[Composition APIについて](https://v3.vuejs.org/guide/composition-api-introduction.html#why-composition-api)

②リアクティブなプロパティの宣言
data()内に相当していたリアクティブなプロパティは、setup()関数内でref(),reactive()で宣言する
⇢ログイン機能のinput要素の値はここに持たせる

※`<template>`で使う値・関数はreturnで返すこと（関数に返り値は必須よね、、）
[Template Refsについて](https://v3.vuejs.org/guide/composition-api-template-refs.html#usage-with-jsx)
#Vue3のコード

#概要
####①アプリ開始処理の記述
####②Composition APIでの記述
####③リアクティブなプロパティの宣言
※今後の開発で概要がどんどん増えていきます。
##①アプリ開始処理の記述
まず、アプリの初期化部分が変更しています

```:~Vue2
import Vue from 'vue'
import ...

new Vue({
  el: '#app',
  components: { App },
  router
})
```
```:Vue3
import { createApp } from 'vue'
import ...

const app = createApp(App)
app.use(router)
app.mount('#app')
```
プラグインの導入部分がVue2までは`new Vue`の前にプラグインを導入していましたが、Vue3では`createApp`で生成されたappインスタンスに対して`.use`でプラグインを導入できます

##②Composition APIでの記述
ここが今の所個人的に感じた一番大きな変更点です
今回は簡単なTodoリストを用いて見てみましょう
![ezgif.com-gif-maker (3).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619648/8ad0c40d-4c79-68a8-9d93-6e9818d8b8d9.gif)


```:~Vue2
<template>
  <div id="app">
    <h1>Todoリスト</h1>
    <input v-model="todo"><br>
    <button @click="addTodo">追加</button>
    <ul>
      <li v-for="(todo, index) in todos" :key="index">{{ todo }} <span @click="removeTodo(index)">X</span></li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      todo: '',
      todos:[]
    }
  },
  methods: {
    addTodo() {
      this.todos.push(this.todo)
      this.todo = ''
    },
    removeTodo(index) {
      this.todos.splice(index, 1)
    }
  }
}
</script>
```
```:Vue3
<template>
  <div id="app">
    <h1>Todoリスト</h1>
    <input v-model="state.todo" /><br />
    <button @click="addTodo">追加</button>
    <ul>
      <li v-for="(todo, index) in state.todos" :key="index">
        {{ todo }} <span @click="removeTodo(index)">X</span>
      </li>
    </ul>
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive } from "vue";
export default defineComponent({
  setup() {
    const state = reactive({ todo: "", todos: [] as string[] });
    const addTodo = () => {
      state.todos.push(state.todo);
      state.todo = "";
    };
    const removeTodo = (index: number) => state.todos.splice(index, 1);
    return { state, addTodo, removeTodo };
  },
});
</script>
```
`<template>`内のHTMLではあまり変化を感じれませんが、JavaScript側では変化を感じ取れると思います。
data()/methodsがsetup()関数の中で定義され、returnで使いたい値を返すだけで済みました。
##③リアクティブなプロパティの宣言
②で扱ったTodoリストでもわかりやすいのですが、今回は簡単なカウントアップの実装で
見てみましょう
![ezgif.com-gif-maker (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619648/2f1098e4-4f11-caaa-dbb6-d518e7fd11b1.gif)

```:~Vue2
<template>
  <div>
    <button @click="countNumber">Count</button>
    <div>{{ count }}</div>
  </div>
</template>

<script>
export default {
  data () {
    return {
      count: 0
    }
  },
  methods: {
    increment () {
      this.count++
    },
  }
}
</script>
```
```:Vue3
<template>
  <div>
    <button @click="countNumber">Count</button>
    <div>{{ count }}</div>
  </div>
</template>

<script lang="ts>
import { defineComponent, ref } from "vue";
export default defineComponent({
  setup() {
    const count = ref(0);
    const countNumber = () => {
      count.value++;
    };
    return {
      count,
      countNumber,
    };
  },
});
</script>

```
どうでしょうか。個人的にはコード量が増えれば増えるほどVue3のComposition APIの恩恵を受けられるのではないかなと感じています。

#感想

まだ、開発始まって3日程度なのでVue３を深くは触れていませんが、今後開発を進めていく中でこの記事にどんどん学んだことを追記していこうと思います。
TypeScriptの学習もこれをきっかけにどんどん進めていこうと思います！
あ～～～～楽し！！！

###参考文献
>先取りVue 3.x !! Composition API を試してみる
>>https://qiita.com/ryo2132/items/f055679e9974dbc3f977

>Vue3.xから採用予定のCompositionAPIとVue2.xを比較してみる
>>https://qiita.com/tomopict/items/95ef9e043c1fc4d9f218