8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

VeriServeAdvent Calendar 2022

Day 11

Option APIからComposition APIへ書き換える

Last updated at Posted at 2022-12-11

Composition APIとは

Option APIではリアクティブな値をUIコンポーネントと切り離すことができなかたったが、切り離せるようにすることでコンポーネント間のロジック共有を行いやすくした技術です。コンポーネントの肥大化に苦しむプロジェクトにはメリットは大きいですが、そうでなければあえて書き直すメリットは小さそうです。また、mixinでロジックの共有化は可能でしたが、mixinを使った実装はアンチパターンとなっており、Vue3からは非推奨となっています

ロジックの分離

では実際にOption APIで実装していたコンポーネントのロジックをComposition APIで分離させてみます。
下記の税率計算を行うOption APIで作成したコンポーネントを例にします。

OptionApi.vue
<template>
  <div>
    <input v-model="taxExcluded" />
    <input v-model="rate" /><span>%</span>
    <span>{{ taxIncluded }}</span>
  </div>
</template>

<script>
export default {
  data() {
    return {
      taxExcluded: 0,
      rate: 10,
    }
  },
  computed: {
    taxIncluded() {
      return this.taxExcluded * this.rate * 0.01 + Number(this.taxExcluded)
    },
  },
}
</script>

一旦ビューとロジックは同じファイル内に置いたままComposition APIに書き換えたコードは下記です。
script内でthisを書かなくてよい代わりにリアクティブな値には.valueでアクセスする必要があります。

CompositionApi.vue
<template>
  <!-- 省略 -->
</template>

<script>
import { defineComponent, ref, computed } from 'vue'

export default defineComponent({
  setup() {
    const taxExcluded = ref(0)
    const rate = ref(10)

    // eslint-disable-next-line no-unused-vars
    const taxIncluded = computed(() => {
      return taxExcluded.value * rate.value * 0.01 + Number(taxExcluded.value)
    })

    return {
      taxExcluded,
      rate,
      taxIncluded,
    }
  },
})
</script>

ロジックとビューを分離した状態にすると下記の様になります。

CalcTax.js
import { ref, computed } from 'vue'

export const calcTax = () => {
  const taxExcluded = ref(0)
  const rate = ref(10)

  const taxIncluded = computed(() => {
    return taxExcluded.value * rate.value * 0.01 + Number(taxExcluded.value)
  })

  return {
    taxExcluded,
    rate,
    taxIncluded,
  }
}
CompositionApi.vue
<template>
  <!-- 省略 -->
</template>

<script>
import { defineComponent } from 'vue'
import { calcTax } from '~/components/tmp/CalcTax.js'

export default defineComponent({
  setup() {
    const { taxExcluded, rate, taxIncluded } = calcTax()

    return {
      taxExcluded,
      rate,
      taxIncluded,
    }
  },
})
</script>

Composition APIの書き方

以下、Option APIとCompositionAPIでのdataやmethodsの書き方の違いです。

data

// Option API
data() {
  return {
    hoge: 0
  }
}

// Composition API
const hoge = ref(0)

methods

// Option API
methods: {
  hogeMethod() {
    this.hoge1 + this.hoge2
  }
}

// Composition API
const hoge = () => {
  hoge1.value + fuga2.value
}

computed

// Option API
computed: {
  hoge() {
    this.hoge1 + this.hoge2
  }
}

// Composition API
const hoge = computed(() => {
  hoge1.value + hoge2.value
})

props

// Option API
props: {
  hoge: {
    type: String,
    default: '',
  }
}

// Composition API
const props = defineProps({
  hoge: {
    type: String,
    default: '',
  }
})

ライフサイクル

Composition APIではライフサイクルが変更されています。
全体的に名称が変わっているほか、beforeCreatecreatedのライフサイクルはsetupで実行されるようになりました。

Option API Composition API
beforeCreate setupに記述
created setupに記述
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeUnmount onBeforeUnmount
unmounted onUnmounted
errorCaptured onErrorCaptured
renderTracked onRenderTracked
renderTriggered onRenderTriggered
activated onActivated
deactivated onDeactivated

おわりに

Composition APIを使うことでロジックを分離できる上に、機能ごとにロジックをまとめやすくもなるためよりVueが使いやすくなりますね。

参考

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?