# セットアップ

このセクションではコード例に単一ファイルコンポーネントの構文を使います。

このガイドはComposition API の導入リアクティブの基礎を既に読んでいることを想定しています。 Composition API に初めて触れる方は、まずそちらを読んでみてください。

# 引数

setup 関数を使う時、2 つの引数を取ります:

  1. props
  2. context

それぞれの引数がどのように使われるのか、深く掘り下げてみましょう。

# プロパティ

setup 関数の第 1 引数は props 引数です。 標準コンポーネントで期待するように、setup 関数内の props はリアクティブで、新しい props が渡されたら更新されます。

// MyBook.vue

export default {
  props: {
    title: String
  },
  setup(props) {
    console.log(props.title)
  }
}
1
2
3
4
5
6
7
8
9
10

WARNING

しかし、props はリアクティブなので、ES6 の分割代入を使うことができません。 props のリアクティブを削除してしまうからです。

もし、props を分割代入する必要がある場合は、setup 関数内で toRefs を使うことによって分割代入を行うことができます:

// MyBook.vue

import { toRefs } from 'vue'

setup(props) {
  const { title } = toRefs(props)

  console.log(title.value)
}
1
2
3
4
5
6
7
8
9

title が省略可能なプロパティである場合、 props から抜けている可能性があります。その場合、 toRefs では title の ref はつくられません。代わりに toRef を使う必要があります:

// MyBook.vue

import { toRef } from 'vue'

setup(props) {
  const title = toRef(props, 'title')

  console.log(title.value)
}
1
2
3
4
5
6
7
8
9

# コンテキスト

setup 関数に渡される第 2 引数は context です。context は 3 つのコンポーネントプロパティを公開する一般的な JavaScript オブジェクトです。:

// MyBook.vue

export default {
  setup(props, context) {
    // Attributes (Non-reactive object)
    console.log(context.attrs)

    // Slots (Non-reactive object)
    console.log(context.slots)

    // Emit Events (Method)
    console.log(context.emit)
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

context オブジェクトは一般的な JavaScript オブジェクトです。すなわち、リアクティブではありません。これは context で ES6 分割代入を安全に使用できることを意味します。

// MyBook.vue
export default {
  setup(props, { attrs, slots, emit }) {
    ...
  }
}
1
2
3
4
5
6

attrsslots はステートフルなオブジェクトです。コンポーネント自身が更新されたとき、常に更新されます。 つまり、分割代入の使用を避け、attrs.xslots.x のようにプロパティを常に参照する必要があります。 また、props とは異なり、 attrsslots はリアクティブではないということに注意してください。 もし、attrsslots の変更による副作用を適用したいのなら、onUpdated ライフサイクルフックの中で行うべきです。

# コンポーネントプロパティへのアクセス

setup が実行されるとき、 コンポーネントインスタンスはまだ作成されていません。そのため、以下のプロパティにのみアクセスすることができます:

  • props
  • attrs
  • slots
  • emit

言い換えると、以下のコンポーネントオプションにはアクセスできません:

  • data
  • computed
  • methods

# テンプレートでの使用

setup がオブジェクトを返す場合、コンポーネントのテンプレート内でオブジェクトのプロパティにアクセスすることができ、 setup に渡された props のプロパティも同じようにアクセスできます:

<!-- MyBook.vue -->
<template>
  <div>{{ collectionName }}: {{ readersNumber }} {{ book.title }}</div>
</template>

<script>
  import { ref, reactive } from 'vue'

  export default {
    props: {
      collectionName: String
    },
    setup(props) {
      const readersNumber = ref(0)
      const book = reactive({ title: 'Vue 3 Guide' })

      // expose to template
      return {
        readersNumber,
        book
      }
    }
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

setup から返された refs は、テンプレート内でアクセスされたときに自動的に浅いアンラップされるので、テンプレート内で .value を使用すべきではないことに注意してください。

# レンダリング関数での使用

setup は同じスコープで宣言されたリアクティブなステートを直接利用することができるレンダリング関数を返すこともできます:

// MyBook.vue

import { h, ref, reactive } from 'vue'

export default {
  setup() {
    const readersNumber = ref(0)
    const book = reactive({ title: 'Vue 3 Guide' })
    // ここでは明示的に ref の値を公開する必要があることに注意してください。
    return () => h('div', [readersNumber.value, book.title])
  }
}
1
2
3
4
5
6
7
8
9
10
11
12

# this の使用

setup() 内では、this は現在のアクティブなインスタンスへの参照にはなりません。 setup() は他のコンポーネントオプションが解決される前に呼び出されるので、setup() 内の this は他のオプション内の this とは全く異なる振る舞いをします。 これは、setup() を他のオプション API と一緒に使った場合に混乱を引き起こす可能性があります。