24
14

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 5 years have passed since last update.

【Vue.js】Composition APIを利用したコンポーネントの作成方法について

Last updated at Posted at 2019-10-28

Composition APIとは

従来のdata, computedを用いたAPIによる問題を改善するための、Vue.jsの新たなコンポーネント作成方法です。
https://vue-composition-api-rfc.netlify.com/#summary

Vue3.xで使用可能になるとのことですが、以下のプラグインを使用することで、Vue2.xでも利用可能です。
https://github.com/vuejs/composition-api

Composition APIを利用したコンポーネントの例

<template>
  <div>
    <p>{{ reactiveValue }}</p>
    <p>{{ computedValue }}</p>
    <div>
      <h1>hoge</h1>
      <p>{{ hogeMethod() }}</p>
      <p>{{ hogeValue }}</p>
    </div>
    <div>
      <h1>fuga</h1>
      <p>{{ fugaMethod() }}</p>
      <p>{{ fugaValue }}</p>
    </div>
  </div>
</template>

<script lang="ts">
import {
  createComponent,
  computed,
  reactive,
  onMounted
} from '@vue/composition-api'

function hoge() {
  const hogeValue = 'hoge'
  const hogeMethod = () => {
    return 'hogeMethod'
  }
  return {
    hogeValue,
    hogeMethod
  }
}

function fuga() {
  const fugaValue = 'fuga'
  const fugaMethod = () => {
    return 'fugaMethod'
  }
  return {
    fugaValue,
    fugaMethod
  }
}

export default createComponent({
  props: {
    value: {
      type: String,
      default: ''
    }
  },
  setup(props, context) {
    onMounted(() => {
      console.log('onMounted')
    })
    const reactiveValue = reactive('reactive value')
    const computedValue = computed(() => props.value)
    const hogeValue = hoge()
    const fugaValue = fuga()
    return {
      computedValue,
      reactiveValue,
      ...hogeValue,
      ...fugaValue
    }
  }
})
</script>

Composition APIを利用してコンポーネントを実装する

ここからは@vue/composition-apiをベースにComposition APIを見ます。

setup()

これまでプロパティに記載していたdata, computed, mountedは全てsetup()の中に内包することになります。
また、templateで使用する値は全てsetupで返却する必要があります。

import {
  createComponent,
  computed,
  reactive,
  onMounted
} from '@vue/composition-api'

setup(props, context) {
    // ライフサイクルメソッドもsetup内で実装する
    onMounted(() => {
      console.log('onMounted')
    })
    const reactiveValue = reactive('reactive value')
    
    const computedValue = computed(() => props.value)
    const hogeValue = hoge()
    const fugaValue = fuga()
    return {
      computedValue,
      reactiveValue,
      ...hogeValue,
      ...fugaValue
    }
  }

setupのメリット

Composition APIを使用することによって、データを機能単位にまとめられるというメリットがあります。

従来のAPIでは、1つのコンポーネントが有する機能Aに対して、data, computedなど、プロパティ単位で分割されていました。そのコンポーネントが更に機能B、Cを有する場合、機能に対するデータがあちこちに分散することで、管理が煩雑になってしまいます。

data() {
  return {
    機能Aのデータ,
    機能Bのデータ,
    機能Cのデータ
  }
},
computed() {
  機能Aのデータ() {...},
  機能Bのデータ() {...},
  機能Cのデータ() {...}
},
methods: {
...

これをComposition APIに置換することで、機能毎にデータをまとめることが出来ます

setup() {
  // 機能Aに対する実装
  const A = () => {...}

  // 機能Bに対する実装
  const B = () => {...}

  // 機能Cに対する実装
  const C = () => {...}

  return {
    A,
    B,
    C
  }
}

setupの分割

setupにほとんどの機能を実装するということで、setupの肥大化が懸念されますが、こちらは、機能毎にfunctionを切ることで、肥大化を防止出来ます。
createComponent外で、functionを作成します。

それぞれのfunctionで、templateで使用したい値を返却するのを忘れてはいけません。
最終的には、functionの返り値をそのままsetupの返り値にしてあげます。

import {
  createComponent,
  computed,
  reactive,
  onMounted
} from '@vue/composition-api'

function hoge() {
  const hogeValue = 'hoge'
  const hogeMethod = () => {
    return 'hogeMethod'
  }
  return {
    hogeValue,
    hogeMethod
  }
}

function fuga() {
  const fugaValue = 'fuga'
  const fugaMethod = () => {
    return 'fugaMethod'
  }
  return {
    fugaValue,
    fugaMethod
  }
}

export default createComponent({
  props: {
    value: {
      type: String,
      default: ''
    }
  },
  setup(props, context) {
    onMounted(() => {
      console.log('onMounted')
    })
    const reactiveValue = reactive('reactive value')
    const computedValue = computed(() => props.value)
    const hogeValue = hoge()
    const fugaValue = fuga()
    return {
      computedValue,
      reactiveValue,
      ...hogeValue,
      ...fugaValue
    }
  }
})

注意点として、機能分離した際の名前の衝突です。
上記例におけるhoge()fuga()に同様のメソッド名がある場合、setupで最後に返却した方に上書きされます。その際には警告などが出力されないため、知らず知らずのうちに上書きが発生する。ということも考えられます。

そのため、機能分離のためのルールを設定するなど、多少人力が必要になるかもしれません。

最後に

Composition APIを用いることで、肥大化したコンポーネントで、1機能の修正のためにdatamethodsをスクロールで往復する状況が改善されるかもしれません。
(そもそも、そのようなコンポーネントは再設計した方がいいかもしれませんが...)

以上です。ありがとうございました。

参考記事

https://qiita.com/ryo2132/items/f055679e9974dbc3f977
https://vue-composition-api-rfc.netlify.com/#api-introduction

参考にさせていただきました。ありがとうございました。

24
14
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
24
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?