# Composition API

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

# setup

Опция компонента, которая выполняется перед созданием компонента, после разрешения входных параметров props, и служит точкой входа для Composition API.

  • Аргументы:

    • {Data} props — входные параметры
    • {SetupContext} context — контекст
  • Типы:

interface Data {
  [key: string]: unknown
}

interface SetupContext {
  attrs: Data
  slots: Slots
  emit: (event: string, ...args: unknown[]) => void
}

function setup(props: Data, context: SetupContext): Data
1
2
3
4
5
6
7
8
9
10
11

Совет

Для получения автодополнения типов для аргументов, передаваемых в setup(), необходимо использовать defineComponent.

  • Пример

    С использованием шаблона:

    <!-- MyBook.vue -->
    <template>
      <div>{{ readersNumber }} {{ book.title }}</div>
    </template>
    
    <script>
      import { ref, reactive } from 'vue'
    
      export default {
        setup() {
          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

    С использованием 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
  • См. также: Composition API setup

# Хуки жизненного цикла

Хуки жизненного цикла можно регистрировать через явно импортируемые onX функции:

import { onMounted, onUpdated, onUnmounted } from 'vue'

const MyComponent = {
  setup() {
    onMounted(() => {
      console.log('примонтирован!')
    })
    onUpdated(() => {
      console.log('обновлён!')
    })
    onUnmounted(() => {
      console.log('размонтирован!')
    })
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

Функции хуков жизненного цикла могут использоваться только синхронно в setup(), так как они полагаются на внутреннее локальное состояние для обнаружения текущего активного экземпляра (экземпляра компонента чей setup() сейчас вызывается). Вызов их без текущего активного экземпляра будет приводить к ошибке.

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

  • Сопоставление между Options 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
  • См. также: Composition API. Хуки жизненного цикла

# Provide / Inject

Функции provide и inject предоставляют возможность инъекции зависимостей. Могут быть вызваны только во время setup() с текущим активным экземпляром.

  • Типы:
interface InjectionKey<T> extends Symbol {}

function provide<T>(key: InjectionKey<T> | string, value: T): void

// без значения по умолчанию
function inject<T>(key: InjectionKey<T> | string): T | undefined

// со значением по умолчанию
function inject<T>(key: InjectionKey<T> | string, defaultValue: T): T

// с функцией-фабрикой
function inject<T>(
  key: InjectionKey<T> | string,
  defaultValue: () => T,
  treatDefaultAsFactory: true
): T
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Vue предоставляет интерфейс InjectionKey — общий тип, расширяющий Symbol. Может использоваться для синхронизации типа внедряемого значения между провайдером и потребителем:

import { InjectionKey, provide, inject } from 'vue'

const key: InjectionKey<string> = Symbol()

provide(key, 'foo') // указание не-строчного значения приведёт к ошибке

const foo = inject(key) // тип foo: string | undefined
1
2
3
4
5
6
7

При использовании строковых ключей или не-типизированных Symbol, тип внедряемого значения необходимо явно объявить:

const foo = inject<string>('foo') // string | undefined
1

# getCurrentInstance

Метод getCurrentInstance позволяет получить доступ к внутреннему экземпляру компонента, что может быть полезно для продвинутых пользователей или разработчиков библиотек.

import { getCurrentInstance } from 'vue'

const MyComponent = {
  setup() {
    const internalInstance = getCurrentInstance()

    internalInstance.appContext.config.globalProperties // доступ к globalProperties
  }
}
1
2
3
4
5
6
7
8
9

Метод getCurrentInstance работает только во время setup или хуков жизненного цикла

При использовании вне setup или хуков жизненного цикла вызывайте getCurrentInstance() в setup и используйте вместо него экземпляр.

const MyComponent = {
  setup() {
    const internalInstance = getCurrentInstance() // работает

    const id = useComponentId() // работает

    const handleClick = () => {
      getCurrentInstance() // НЕ БУДЕТ РАБОТАТЬ
      useComponentId() // НЕ БУДЕТ РАБОТАТЬ

      internalInstance // работает
    }

    onMounted(() => {
      getCurrentInstance() // работает
    })

    return () =>
      h(
        'button',
        {
          onClick: handleClick
        },
        `uid: ${id}`
      )
  }
}

// также работает при вызове в функции композиции
function useComponentId() {
  return getCurrentInstance().uid
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

Deployed on Netlify.
Последнее обновление: 2021-02-04, 21:13:33 UTC