# Функция setup

Этот раздел использует синтаксис однофайловых компонентов для примеров кода

Подразумевается, что вы уже изучили и разобрались с разделами Введение в Composition API и Основы реактивности. Если нет — прочитайте их сначала.

# Аргументы

При использовании функции setup можно передавать два аргумента:

  1. props — входные параметры
  2. context — контекст

Давайте разберёмся с тем, как можно использовать каждый из них.

# Входные параметры

Первым аргументом setup передаются входные параметры props. Как и следует ожидать в обычном компоненте, props внутри функции setup реактивны и будут обновляться при передаче новых значений.

// MyBook.vue

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

ВНИМАНИЕ

Поскольку props реактивны, то использовать деструктуризацию ES6 нельзя, потому что это уберёт реактивность со входных параметров.

Если необходимо использовать деструктуризацию входных параметров, это можно сделать используя toRefs внутри функции setup:

// 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. Вместо этого потребуется использовать 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, будет контекст context. Это обычный объект JavaScript, который предоставляет доступ к трём свойствам компонента:

// MyBook.vue

export default {
  setup(props, context) {
    // Атрибуты (нереактивный объект)
    console.log(context.attrs)

    // Слоты (нереактивный объект)
    console.log(context.slots)

    // Генерация событий (метод)
    console.log(context.emit)
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Поскольку объект context будет обычным объектом JavaScript, т.е. он нереактивный, а значит можно спокойно использовать деструктуризацию ES6 для context.

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

Свойства attrs и slots — объекты с состоянием, которые будут всегда обновляться при обновлении самого компонента. Это значит, что следует избегать деструктуризации для них и всегда ссылаться на свойства как attrs.x или slots.x. Также обратите внимание, что в отличие от props, свойства attrs и slots НЕ РЕАКТИВНЫ. Если необходимо применить побочные эффекты, основанные на изменениях attrs или slots, то следует делать это внутри жизненного цикла onUpdated.

# Доступ к свойствам компонента

При выполнении setup экземпляр компонента ещё не будет создан. Поэтому возможно получить доступ только к следующим свойствам:

  • props
  • attrs
  • slots
  • emit

Другими словами, не будет доступа к следующим опциям компонента:

  • data
  • computed
  • methods

# Использование в шаблонах

Если функция setup возвращает объект, то его свойства будут также доступны в шаблоне компонента, как и свойства props, переданные в setup:

<!-- 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' })

      // всё объявленное будет доступно в шаблоне
      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

Обратите внимание, refs возвращаемые из setup будут автоматически неглубоко разворачиваться при обращениях в шаблоне, поэтому в шаблонах указывать .value не потребуется.

# Использование в render-функциях

Функция setup также может возвращать render-функцию, которая может напрямую использовать реактивное состояние, объявленное в той же области видимости:

// 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() вызывается до разрешения других опций компонента, то this внутри setup() будет вести себя несколько иначе, чем this в других опциях. Это может привести к путанице при использовании setup() вместе с другими Options API.

Deployed on Netlify.
Последнее обновление: 2021-02-25, 10:16:09 UTC