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の概要を一気に解説

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

Vue3による改善
①処理を一箇所にまとめる。
→Vue2だとdataで定義した変数をmethodsなどで使用するわけで、処理が分散しています。
ここらへんのイメージは、URL記載の図を見るとイメージしやすいでしょうか。
Vue.js
Vue3ではsetup関数を用いて、一つに処理をまとめることができるようになりました!
②コードの再利用
Vue2で例えばmethodsの処理を他のコンポーネントでも利用したい場合は、Mixinを使う方法がありました。しかし、これが非常に読みにくく、名前の衝突が発生する恐れがありました。Vue3では、これも改善されているようです。
③Composition API
Composition APIの導入により、Typescriptとの相性も良くなりました。

Vue2

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

<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だとこんな感じ。

<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

Vue3でのルーティング

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

<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?
Vue 3 + Composition APIの概要:Todoアプリを作成する