概要
現在参画中のプロジェクトでアプリのフロントエンド開発環境がVue2からVue3に変わろうとしているタイミングに差し掛かったため、これを機に自身もリマインドを書こうと思います。
ver3がベータ版だったこともあり、使用がメジャーになるまでは個人開発でもPENDしている状態だったのですが、こちらも機を見て導入したいです。
本記事の前提
Vue 2では、基本的に Options API
という記述方法を使うのがメジャーでした。
Vue 3ではこれに加え、 Composition API
という記述方法も使えるようになります。
(Vue 2でも拡張機能として導入が可能だったようですが、マイナーと考えます)
どちらの記述も条件付きで使える状態ではあるため厳密にはバージョンの違いという位置付けではないですが、今回の記事ではメジャーな記法になると考えられる
- Vue 2: Options API
- Vue 3: Composition API
に置き換えて比較してみます。
Options API
公式より引用したソースを元に比較してみます。
まずOptions APIについてですが、おおよその形としては次のような構成があります。
- components: 外部から参照するコンポーネント、インポートが必要
- props: 上位コンポーネントから継承するデータプロパティ、変更不可
- data: 当該コンポーネント内での処理に使用するデータプロパティ、変更可
- computed: 利用する値が変化すると自動的に再計算される関数
- watch: 特定の変数やオブジェクトを監視し、値の変化時に自動で処理を実行する
- methods: 任意のタイミングで呼び出して使用する処理
// src/components/UserRepositories.vue
export default {
components: { RepositoriesFilters, RepositoriesSortBy, RepositoriesList },
props: {
user: {
type: String,
required: true
}
},
data () {
return {
repositories: [], // 1
filters: { ... }, // 3
searchQuery: '' // 2
}
},
computed: {
filteredRepositories () { ... }, // 3
repositoriesMatchingSearchQuery () { ... }, // 2
},
watch: {
user: 'getUserRepositories' // 1
},
methods: {
getUserRepositories () {
// `this.user` を使用してユーザーのリポジトリを取得します
}, // 1
updateFilters () { ... }, // 3
},
mounted () {
this.getUserRepositories() // 1
}
}
Composition API
次にComposition APIです。
基本的な機能はVue 2を継承している部分もありますが、根本的な記述方法が異なる部分があります。
上記のOptions APIソースを書き換えた場合と比較してみます。
// src/components/UserRepositories.vue
import { defineComponent, reactive, computed, watch, toRefs } from 'vue';
export default defineComponent({
components: { RepositoriesFilters, RepositoriesSortBy, RepositoriesList },
props: {
user: {
type: String,
required: true
}
},
setup(_, context) {
const state = reactive({
repositories: [], // 1
filters: { ... }, // 3
searchQuery: '' // 2
});
// computed
const filteredRepositories = computed(() => {
...
}; // 3
const repositoriesMatchingSearchQuery = computed(() => {
...
}; // 2
// watch: プリミティブ型のrefの場合
const user = ref(0);
watch(user, (next, prev) => {
//
});
// methods
function getUserRepositories () {
// `this.user` を使用してユーザーのリポジトリを取得します
} // 1
function updateFilters () { ... } // 3
// computed, methodsを追記し、使用可能に
return Object.assign(
toRefs(state),
filteredRepositories,
repositoriesMatchingSearchQuery,
getUserRepositories,
updateFilters,
context
);
},
};
全体的に変わった箇所は以下になります。
- ライブラリインポート
- 宣言なしで支えていたプロパティをimportする必要があります。
- 今回の例では、
computed
,watch
が該当
- コンポーネント定義
-
export default
としていた部分は、defineComponent
ライブラリを使って宣言する形になります。(インポート必要)
-
- components, props
- 記法において基本的な構成は変わりません。
- プロパティ定義
- 個人的に一番変わった部分と感じている部分ですが、
setup()
関数内にプロパティ類をまとめる形となっています。 - また、定義したとしても
Object.assign
で宣言する必要があり、こちらで記載していないものは機能できなくなります。- data:
state
に置き換わります。 - computed: const + computed()関数
- watch: 監視対象(プリミティブ型や配列等)の種類によって記述方法を変える必要があります。
- methods: 従来のJS/TSと同じく
function
で宣言します。(async等も同様)
- data:
- 個人的に一番変わった部分と感じている部分ですが、
その他、根本的な仕様変更としては次のようなものがあります。
・data参照
this.data1 → state.data1
・nextTick: Vueライブラリでインポートが必要
this.$nextTick() → nextTick()
・auth: AuthPlugin
プラグインが必要
this.$auth.user → authAPI.user
といったように、全体的に this
関数の使用が不要となりました。
全体的な使用感
プロジェクトでは新旧入り混じっているソースでも破壊的なエラーが出ているわけではないのでフラットに使える部分もあるようですが、これまでデフォルトで参照できていたプロパティやライブラリがインポートしないと使えないようになっているという印象が強いです。
- コードのシンプルさ
- TypeScriptの全面サポート
- 開発速度・実行速度もUP
などが挙げられるVue3のメリットを現時点では実感できていませんが、改めて学習を続け慣れていけたらと思います。