🦁
最低限わかるVue Composition API
この資料について
この資料はVue2.0で動くプロダクトでVue Composition APIについて簡単に解説し、関心をもってもらうために用いた際のものです。
対象読者は以下を想定しています。
- VueのOption API(今までの書き方)をさわったことがある
- React Hooksの経験がない
より詳細な知識は公式ドキュメントよりご参照ください。
Vue 3系のコンポジションapi について
ってなんですか
- 今までとは違う書式でvueを書ける記法
- 今後主流になりそう
- reactのhooks apiに強く影響をうけている
https://ja.reactjs.org/docs/hooks-reference.html
なにがうれしいのか
- 機能単位でカプセル化っぽくできる
- vue独特の書式が減る(dataプロパティとか暗黙のthisとか)
いままでの書き方
※Option APIと呼ぶ
<template>
<div>
<h1>Counter App</h1>
<div>{{ count }}</div>
<button @click="increment">increment</button>
</div>
</template>
<script>
export default {
data() {
return {
count: 0
}
},
methods: {
increment() {
this.count++
}
}
}
</script>
新しい書き方
Vue3.0 composition apiだと
<template>
<div>
<h1>Counter App</h1>
<div>{{ state.count }}</div>
<button @click="increment">increment</button>
</div>
</template>
<script>
import { reactive } from 'vue'
export default {
setup() {
const state = reactive({ count: 0 })
const increment = () => {
state.count++
}
return {
state,
increment
}
}
}
<script>
こまかく見ていくと
step1
export default {
setup() {
// setupメソッドの中に処理をまとめて書く
}
}
step2
import { reactive } from 'vue'
export default {
setup() {
// オブジェクトをreactiveメソッドに通す
const state = reactive({ count: 0 })
}
}
step3
export default {
setup() {
const state = reactive({ count: 0 })
// 状態の更新関数をつくる
const increment = () => {
state.count++
}
}
}
step4
export default {
setup() {
const state = reactive({ count: 0 })
const increment = () => {
state.count++
}
// vue templateで使うものをreturnする
return {
state,
increment
}
}
}
これで何が変わるの?
setup内を「ただの関数」として分離できる
import { reactive } from 'vue'
function useCounter () {
const state = reactive({ count: 0 })
const increment = () => {
state.count++
}
return {
state,
increment
}
}
export default {
setup() {
const { state, incremet } = useCounter()
return {
state,
incremet
}
}
}
くわえて
任意の処理を別の関数として分離できる
decrementを別の関数として分離してみた
<template>
<div>
<h1>Counter App</h1>
<div>{{ count1.count }}</div>
<button @click="increment">increment</button>
<div>{{ count2.count }}</div>
<button @click="decrement">decrement</button>
</div>
</template>
<script>
import { reactive } from 'vue'
function useCounter () {
const count1 = reactive({ count: 0 })
const increment = () => {
count1.count++
}
return {
count1,
increment
}
}
function useCounter2 () {
const count2 = reactive({ count: 0 })
const decrement = () => {
count2.count--
}
return {
count2,
decrement
}
}
export default {
setup() {
return {
...useCounter(),
...useCounter2()
}
}
}
<script>
class構文でカプセル化するのと
なんか似てる
これができると
機能単位で独立したモジュールが作れる
useCounter.js というファイル
useCounter.js
import { reactive } from 'vue'
export function useCounter () {
const count1 = reactive({ count: 0 })
const increment = () => {
count1.count++
}
return {
count1,
increment
}
}
useCounter2.js というファイル
useCounter2.js
import { reactive } from 'vue'
export function useCounter2 () {
const count2 = reactive({ count: 0 })
const decrement = () => {
count2.count--
}
return {
count2,
decrement
}
}
Counter.vue に import するだけでカウンター機能が使える
<template>
<div>
<h1>Counter App</h1>
<div>{{ count1.count }}</div>
<button @click="increment">increment</button>
<div>{{ count2.count }}</div>
<button @click="decrement">decrement</button>
</div>
</template>
<script>
import { useCounter } from '@/hooks/useCounter'
import { useCounter2 } from '@/hooks/useCounter2'
export default {
setup() {
const { count1, increment } = useCounter()
const { count2, decrement } = useCounter2()
return {
count1,
increment,
count2,
decrement
}
}
}
<script>
ということは
Q.
他のコンポーネントに useCounter2 の機能だけを入れたいとき
どうする?
-
- useCounter2.jsの中身をコピペする
-
- useCounter2.jsをインポートする
A.
- useCounter2.jsをインポートする
いろんな画面共通で使う機能を切り出せば
インポートするだけでお手軽に画面がつくれる
夢、広がる!
@vue/composition-apiパッケージを導入すれば
Vue2系のプロジェクトでも使うことができます
また、省略したけれど、typescriptとの相性もよくなります
参考資料
おわり
口頭解説前提の資料のため、ドキュメント単体では理解しづらい面もあるかもしれません。
いいねやご指摘あればぜひお願いいたします。
Discussion