Composition API: setup()
Użycie podstawowe
Funkcja setup()
służy jako główny punkt wejścia do korzystania z Composition API w komponentach w następujących przypadkach:
- Używanie Composition API bez kroku budowania;
- Integracja kodu opartego na Composition API w komponencie korzystającym z Options API.
Note
Uwaga Jeśli używasz Composition API z komponentami jednoplikowymi (Single-File Components), zdecydowanie zaleca się stosowanie składni <script setup>
dla bardziej zwięzłej i ergonomicznej składni.
Możemy zadeklarować reaktywny stan, używając Reactivity APIs i udostępnić go w szablonie, zwracając obiekt z funkcji setup(). Właściwości na zwróconym obiekcie będą również dostępne na instancji komponentu (jeśli używane są inne opcje):
vue
<script>
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
// udostępnianie funkcji API szablonów i innych opcji
return {
count
}
},
mounted() {
console.log(this.count) // 0
}
}
</script>
<template>
<button @click="count++">{{ count }}</button>
</template>
refs zwracane z setup są automatycznie płytko rozpakowywane podczas dostępu do nich w szablonie, więc nie musisz używać .value
, aby się do nich odwołać. Są one również rozpakowywane w ten sam sposób podczas dostępu przez this
.
setup()
sam w sobie nie ma dostępu do instancji komponentu - this
będzie miało wartość undefined
wewnątrz setup()
. Możesz uzyskać dostęp do wartości udostępnionych przez Composition API z poziomu Options API, ale nie odwrotnie.
setup()
powinien zwracać obiekt synchronicznie. Jedynym przypadkiem, kiedy można użyć async setup()
, jest sytuacja, gdy komponent jest potomkiem komponentu Suspense.
Dostęp do propsów
Pierwszym argumentem w funkcji setup
jest argument props
. Tak jak można oczekiwać w standardowym komponencie, props
wewnątrz funkcji setup
są reaktywne i będą aktualizowane po przekazaniu nowych rekwizytów.
js
export default {
props: {
title: String
},
setup(props) {
console.log(props.title)
}
}
Zauważ, że jeśli zdestrukturyzujesz obiekt props
, zdestrukturyzowane zmienne stracą reaktywność. Dlatego zaleca się, aby zawsze uzyskiwać dostęp do rekwizytów w postaci props.xxx
.
Jeśli naprawdę potrzebujesz zdestrukturyzować rekwizyty lub chcesz przekazać rekwizyt do zewnętrznej funkcji, zachowując reaktywność, możesz to zrobić za pomocą API toRefs() i toRef():
js
import { toRefs, toRef } from 'vue'
export default {
setup(props) {
// przekształć `props` w obiekt refs, a następnie zdestrukturyzuj
const { title } = toRefs(props)
// `title` jest referencją, która śledzi `props.title`
console.log(title.value)
// LUB, przekształć pojedynczą właściwość w `props` na ref
const title = toRef(props, 'title')
}
}
Setup Context
Drugim argumentem przekazywanym do funkcji setup
jest obiekt Setup Context. Obiekt kontekstu udostępnia inne wartości, które mogą być użyteczne wewnątrz setup
:
js
export default {
setup(props, context) {
// Atrybuty (Niereaktywne obiekty, odpowiednik do $attrs)
console.log(context.attrs)
// Sloty (Niereaktywne obiekty, odpowiednik do $slots)
console.log(context.slots)
// Emit (Funkcja, odpowiednik do $emit)
console.log(context.emit)
// Ujawnia właściwości publiczne (Funckja)
console.log(context.expose)
}
}
Obiekt kontekstowy nie jest reaktywny i może być bezpiecznie zdestrukturyzowany:
js
export default {
setup(props, { attrs, slots, emit, expose }) {
...
}
}
attrs
i slots
to obiekty posiadające stan, które są zawsze aktualizowane, gdy aktualizowany jest sam komponent. Oznacza to, że należy unikać ich destrukturyzacji i zawsze odwoływać się do właściwości jako attrs.x
lub slots.x
. Należy również pamiętać, że w przeciwieństwie do props
, właściwości attrs
i slots
nie są reaktywne. Jeśli zamierzasz zastosować side effects oparte na zmianach w attrs
lub slots
, powinieneś zrobić to wewnątrz funkcji cyklu życia onBeforeUpdate
.
Ujawnianie właściwości publicznych
expose
to funkcja, której można użyć do wyraźnego ograniczenia właściwości ujawnianych, gdy instancja komponentu jest dostępna przez komponent nadrzędny za pośrednictwem [template refs] (/guide/essentials/template-refs#ref-on-component):
js
export default {
setup(props, { expose }) {
// instancja komponentu jest „zamknięta”
// tj. nie ujawniaj niczego rodzicowi
expose()
const publicCount = ref(0)
const privateCount = ref(0)
// selektywnie ujawnia stan lokalny
expose({ count: publicCount })
}
}
Użycie z funkcjami renderowania
setup
może również zwracać render function, która może bezpośrednio korzystać ze stanu reaktywnego zadeklarowanego w tym samym zakresie:
js
import { h, ref } from 'vue'
export default {
setup() {
const count = ref(0)
return () => h('div', count.value)
}
}
Zwrócenie funkcji renderującej uniemożliwia nam zwrócenie czegokolwiek innego. Wewnętrznie nie powinno to stanowić problemu, ale może być problematyczne, jeśli chcemy udostępnić metody tego komponentu komponentowi nadrzędnemu za pośrednictwem odwołań do szablonu.
We can solve this problem by calling expose()
:
js
import { h, ref } from 'vue'
export default {
setup(props, { expose }) {
const count = ref(0)
const increment = () => ++count.value
expose({
increment
})
return () => h('div', count.value)
}
}
Metoda increment
byłaby wtedy dostępna w komponencie nadrzędnym poprzez szablon ref.