Vue3とVue2の2パターンでTodoリストを作成してみる。

ただ今、午前2:00ごろ。
何でこんな時間に記事を作成しているかというと、9／16、9/17は00：00～05：00で「Nuxt Nation Conference」が開かれているので、夜ふかしをしています。

Vue3への移行に伴い、どんな変化があったのか。
まずは何となく把握しようと思い、Vue3とVue2の2パターンでTodoリストを作成してみました。

そのソースコードを公開します。
Vue3に踏み込めていないよ！というVueユーザーにも、両者を比較することで概要はつかめるかなと。

**Nuxtで記述してます！**

###お願い
本記事執筆者は、実務未経験のプログラミング初学者です。Vue3関連の情報はまだまだ少ないこともあって、記述に間違いや不自然な点はあるかと思います。
コードをそのまま参考にはしないことを推奨します。
Vue3ってこんな感じなんだあ、と思ってもらうことを目的に作成しております。
また気になる点があれば、コメントにて教えていただけると助かります。


#Vue3で良くなったこと
簡単にですが、Vue3で改善されたことを記述しておきます。
詳しく知りたい方は、Youtubeに参考になる動画がありますのでご覧下さい。
[Vue3とComposition APIの概要を一気に解説](https://www.youtube.com/watch?v=XIpQLdcqawc)

Vue2の制約
①コンポーネントの肥大化、処理の分散化
②コードの再利用性
③Typescriptとの相性

Vue3による改善
①処理を一箇所にまとめる。
→Vue2だとdataで定義した変数をmethodsなどで使用するわけで、処理が分散しています。
ここらへんのイメージは、URL記載の図を見るとイメージしやすいでしょうか。
[Vue.js](https://v3.vuejs.org/guide/composition-api-introduction.html#:~:text=write%20them%20in%20the%20first%20place.)
Vue3ではsetup関数を用いて、一つに処理をまとめることができるようになりました！
②コードの再利用
Vue2で例えばmethodsの処理を他のコンポーネントでも利用したい場合は、Mixinを使う方法がありました。しかし、これが非常に読みにくく、名前の衝突が発生する恐れがありました。Vue3では、これも改善されているようです。
③Composition API
Composition APIの導入により、Typescriptとの相性も良くなりました。

#Vue2
Vue2で記述したのが、下記のコードになります。

```typescript
<script lang="ts">
import Vue from "vue";
type Item = {
  done: boolean;
  content: string;
}
type DataType = {
  newTodo: string;
  todos: Item[];
};
export default Vue.extend({
  name: "Page",
  data(): DataType {
    return {
      newTodo: '',
      todos: []
    };
  },
  methods: {
    //Todoを追加する
    addNewTodo() {
      this.todos.push({
        done: false,
        content: this.newTodo,
      });
      this.newTodo = '';
    },
    //Todoの完了未完了をクリックで切り替える
    toggleDone(index: number) {
      this.todos[index].done= true;
    },
    //Todoを削除
    deleteTodo(index: number) {
      this.todos.splice(index);
    },
    //Todoを一括で完了状態にする
    markAllDone() {
      this.todos.forEach((todo) => todo.done = true);
    },
    //Todoを一括で削除する 
    deleteAllTodo() {
      this.todos = [];
    }
  },
});
</script>
```

#Vue3
Vue3だとこんな感じ。

```typescript
<script lang="ts">
import { defineComponent, ref } from '@nuxtjs/composition-api'
type Item = {
  done: boolean;
  content: string;
}
export default defineComponent({
  setup() {
    //Todoを追加する
    let newTodo = ref<string>("");
    let todos = ref<Item[]>([]);
    function addNewTodo() {
      todos.value.push({
        done: false,
        content: newTodo.value,
      });
      newTodo.value = ''
    }
    //Todoの完了未完了をクリックで切り替える
    function toggleDone(index: number) {
      todos.value[index].done = true
    }
    //Todoを削除
    function deleteTodo(index: number) {
      todos.value.splice(index);
    }
    //Todoを一括で完了状態にする
    function markAllDone() {
      todos.value.forEach((todo) => todo.done = true);
    }
    //Todoを一括で削除する
    function deleteAllTodo() {
      todos.value = []
    }
    return {
      newTodo,
      todos,
      addNewTodo,
      toggleDone,
      deleteTodo,
      markAllDone,
      deleteAllTodo
    };
  },
});
</script>
```

##全体のソースコード
[github](https://github.com/kondo97/Vue3-vs-Vue2)

##Vue3でのルーティング
Vue2だとthis.$router.push('/')でルーティングするのですが、Vue3だと下記のような記述になります。

```typescript
<script lang="ts">
import { defineComponent, useRouter} from '@nuxtjs/composition-api'
export default defineComponent({
  setup(){
    const router = useRouter()
    function selectVue3() {
      router.push('/Vue3')
    }
    function selectVue2() {
      router.push('/Vue2')
    }
    return {
      selectVue3,
      selectVue2
    }
  }
});
</script>
```

##感想
初めてVue2を触ったときは独特だなあと思っていたけど、慣れてくると書きやすくて読みやすかったです。
Vue3は慣れてない今の段階でも、しっくりくるものがある。独特さが薄れた気がします。

今後は、computedやcreatedといった他の処理や、vuexについても検証していきたいです。

###参考
[Why the CompositionAPI?](https://www.youtube.com/watch?v=6HUjDKVn0e0)
[Vue 3 + Composition APIの概要：Todoアプリを作成する](https://www.youtube.com/watch?v=rncY1tlWShM)