Vue3を触ってみた感想
2020年9月にVue3が正式リリースされ、だいぶ安定してきた感じがするので、 ここのところ Vue.js + TypeScript を使った個人開発をしています。
扱い方も慣れてきたので、使ってみた感想を書いていきたいと思います。
# v-model の破壊的変更
Vue2 までの構文では v-model は value と @input のシンタックスシュガーでしたが、
Vue3 ではこれが modelValue と @update:modelValue に変わっています。
この変更によって既存のVue2プロジェクトをVue3に移行する際には大幅な書き換えが必要となっており、 Vueに依存するライブラリが軒並み使えなくなってしまうという事態が発生。
今まで使っていたサードパーティ製ライブラリは今後対応されるかどうかも怪しい感じですね...
主 要 な 構 文 に 破 壊 的 変 更 入 れ て ん じ ゃ ね え よ 。
# Composition API の TypeScript支援
Vue3 の一番のトピックといえば Composition API ですね。
TypeScriptによる型推論が完全に効くことに加え、 methods や computed といった"処理"を別ファイルに分離できるようになったのが特徴です。
例えば v-model の実装では、computed の getter/setter 機能を使ったコードを使っていましたが、 これを共通化することができました。
// Vue2 までの書き方
export default {
  computed: {
    _value: {
      get () {
        return this.value
      },
      set (value) {
        this.$emit('input', value)
      },
    },
    _max: {
      get () {
        return this.max
      },
      set (max) {
        this.$emit('update:max', max)
      },
    },
  },
}
// Vue3 での新しい書き方
import vModel from '@/utils/vModel'
export default {
  setup (props, context) {
    const value = vModel('modelValue', props, context)
    const max = vModel('max', props, context)
  },
}
// vModel.ts
import { computed, SetupContext } from 'vue'
export default (key: string, props: { [key: string]: unknown }, { emit }: SetupContext) => computed({
  get: () => props[key],
  set: updateValue => emit(`update:${key}`, updateValue),
})
こんな感じで共通処理にしてしまうことで、コンポーネント側は処理を呼び出すだけのシンプルな記述ができるようになり、 処理の見通しが非常に良くなったのは好印象。
コンポーネントには具体的な処理ではなく、 このコンポーネントでは何をするのか という振る舞いだけが書かれる形にできます。
Vue2 にも mixin があったじゃん?
ファイルの分離って意味では Vue2 にも mixin という構文がありましたけど、あれはダメですね。
PHP の Trait と同じで、表から見えないメソッドが勝手に生えるので見通しは逆に悪くなるし、基本的に使わないのが正解だと思います。
# 総評
今回は使い勝手について簡単にご紹介しましたが、この他にもバージョンアップらしくコンパイル時のサイズや処理の高速化など内部的な変更も多数あるようで、 もともと大規模開発向きではなかったVue.jsも、大規模な開発に耐えられるような形になってきたことは期待が持てます。
とは言え、 v-model の破壊的変更は致命的ですね。 これによって主要なライブラリが出揃うまでに時間がかかってしまう点や、 Nuxt や VueRouter, Vuex などの使い勝手も大幅に変わってしまう可能性が高いです。
これは AngularJS が衰退したのと同じ道な気がして仕方ないし、今後に新規で開発を行うとなった時に、Vue.js が選択肢から外れる可能性が上がりました。
だってできることがReactと大して変わらねーもん。
この記事をシェア

