Vue3 API de composition

Vue3 Composition API est principalement utilisée pour améliorer la réutilisabilité de la logique de code dans les grands composants.

À mesure que la complexité métier augmente, les composants traditionnels voient la taille de leur code augmenter, et toute la logique du code devient difficile à lire et à comprendre.

L'endroit où Vue3 utilise la Composition API est la fonction setup().setup。

Dans setup, nous pouvons regrouper des parties du code par préoccupations logiques, puis extraire des extraits de logique et les partager avec d'autres composants. Par conséquent, la Composition API nous permet d'écrire du code plus organisé.

Comparez les deux extraits de code suivants :

1. Composants traditionnels

2. Composition API


Composant setup

La fonction setup() s'exécute avant que le composant ne soit créé (created()).

La fonction setup() accepte deux paramètres : props et context.

Le premier paramètre, props, est réactif et sera mis à jour lorsque de nouvelles props sont transmises.

Le deuxième paramètre, context, est un objet JavaScript simple. C'est un objet de contexte qui expose d'autres valeurs qui peuvent être utiles dans setup.

Remarque :Dans setup, vous devez éviter d'utiliser this, car il ne trouvera pas l'instance du composant. L'appel de setup se produit avant que les propriétés data, les propriétés computed ou les méthodes ne soient résolues, on ne peut donc pas y accéder dans setup.

L'exemple suivant utilise la Composition API pour définir un compteur :

Exemple (src/APP.vue)

<template>
    <div>
        <p>Exemple de compteur : {{ count }}</p>
        <input @click="myFn" type="button" value="Cliquez sur moi pour ajouter 1">
    </div>
</template>

<script>
import {ref, onMounted} from 'vue';

export default {
    setup(){
// Définir une variable avec une valeur initiale de 0. Utiliser la méthode ref pour l'assigner ; si assignée directement, les modifications de la variable ne mettront pas à jour l'interface utilisateur.
        let count = ref(0);

// Définir l'événement de clic myFn
        function myFn(){
            console.log(count);
            count.value += 1;
        }
       
// Lorsque le composant est monté, nous utilisons le hook onMounted pour enregistrer des messages
        onMounted(() => console.log('component mounted!'));

// Les variables ou méthodes définies avec la Composition API sont disponibles dans le template.
return {count, myFn} // Les fonctions retournées se comportent de la même manière que les méthodes
    }
}
</script>

Dans Vue 3.0, nous pouvons utiliser une nouvelle fonction ref pour rendre n'importe quelle variable réactive utilisable n'importe où, comme indiqué ci-dessous :

import { ref } from 'vue'

let count = ref(0);

ref()La fonction crée un objet de données réactif basé sur la valeur donnée. La valeur de retour est un objet avec une seule.value.value propriété.

Dans la fonction setup(), les données réactives créées par ref() renvoient un objet, vous devez donc utiliser.value.value pour y accéder.

Exemple

import { ref } from 'vue'

const counter = ref(0)

console.log(counter) // { value: 0 }
console.log(counter.value) // 0

counter.value++
console.log(counter.value) // 1

Hooks de cycle de vie de l'API de composition de Vue

Dans Vue2, nous implémentons les fonctions de hook de cycle de vie de la manière suivante :

Exemple

export default {
  beforeMount() {
    console.log('V2 beforeMount!')
  },
  mounted() {
    console.log('V2 mounted!')
  }
};

Dans l'API de composition de Vue3, les fonctions de hook de cycle de vie peuvent être implémentées danssetup()la fonction setup() en utilisantondes fonctions préfixées par on :

Exemple

import { onBeforeMount, onMounted } from 'vue';
export default {
  setup() {
    onBeforeMount(() => {
      console.log('V3 beforeMount!');
    })
    onMounted(() => {
      console.log('V3 mounted!');
    })
  }
};

Le tableau suivant montre la correspondance entre l'API Options et l'API de composition, y compris comment appeler les hooks de cycle de vie à l'intérieur de setup() :

API à base d'options de Vue2API de composition de Vue
beforeCreatesetup()
createdsetup()
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestroyonBeforeUnmount
destroyedonUnmounted
errorCapturedonErrorCaptured

Étant donné que setup s'exécute autour des hooks de cycle de vie beforeCreate et created, il n'est pas nécessaire de les définir explicitement. En d'autres termes, tout code écrit dans ces hooks doit être écrit directement dans la fonction setup.

Ces fonctions acceptent une fonction de rappel qui sera exécutée lorsque le hook est appelé par le composant :

Exemple

setup() {
...
    // Lorsque le composant est monté, nous utilisons le hook onMounted pour enregistrer des messages
    onMounted(() => console.log('component mounted!'));
...
}

Références de template

Lorsque vous utilisez l'API de composition, les références réactives et les références de template sont des concepts unifiés.

Pour obtenir une référence à un élément ou à une instance de composant dans le template, nous pouvons déclarer une ref comme d'habitude et la retourner depuis setup() :

Exemple

<template>
  <div ref="root">Ceci est un élément racine</div>
</template>

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

  export default {
    setup() {
      const root = ref(null)

      onMounted(() => {
        // L'élément DOM sera assigné à la ref après le rendu initial
        console.log(root.value) // <div>Ceci est un élément racine</div>
      })

      return {
        root
      }
    }
  }
</script>

Dans l'exemple ci-dessus, nous exposons root dans le contexte de rendu et le lions à l'élément div comme sa ref via ref="root".

Les refs utilisées comme templates se comportent comme n'importe quelle autre ref : elles sont réactives et peuvent être passées à (ou renvoyées par) des fonctions composites.

Utilisation dans v-for

Lorsqu'elles sont utilisées dans v-for, les refs de template ne sont pas traitées spécialement dans la Composition API. À la place, utilisez une ref de fonction pour une gestion personnalisée :

Exemple

<template>
  <div v-for="(item, i) in list" :ref="el => { if (el) divs[i] = el }">
    {{ item }}
  </div>
</template>

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

  export default {
    setup() {
      const list = reactive([1, 2, 3])
      const divs = ref([])

      // Assurez-vous de réinitialiser la ref avant chaque mise à jour
      onBeforeUpdate(() => {
        divs.value = []
      })

      return {
        liste,
        divs
      }
    }
  }
</script>

Surveillance des refs de template

L'observation des références de template pour détecter les changements peut remplacer les hooks de cycle de vie illustrés dans les exemples précédents.

Cependant, une différence clé avec les hooks de cycle de vie est que watch() et watchEffect() s'exécutent avant que le DOM ne soit monté ou mis à jour, ce qui a des effets secondaires : lorsque l'observateur s'exécute, les références de template n'ont pas encore été mises à jour.

Exemple

<template>
  <div ref="root">Ceci est un élément racine</div>
</template>

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

  export default {
    setup() {
      const root = ref(null)

      watchEffect(() => {
        // Cet effet secondaire s'exécute avant la mise à jour du DOM, donc la référence de template ne contient pas encore de référence à l'élément.
        console.log(root.value) // => null
      })

      return {
        root
      }
    }
  }
</script>

Par conséquent, les observateurs utilisant des références de template doivent être définis avec l'option flush: 'post', qui exécutera les effets secondaires après la mise à jour du DOM, garantissant que les références de template restent synchronisées avec le DOM et référencent le bon élément.

Exemple

<template>
  <div ref="root">Ceci est un élément racine</div>
</template>

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

  export default {
    setup() {
      const root = ref(null)

      watchEffect(() => {
        console.log(root.value) // => <div>This is a root element</div>
      },
      {
        flush: 'post'
      })

      return {
        root
      }
    }
  }
</script>

Référence API

NuméroAPI et descriptionExemple
1setup()
La fonction d'entrée dans la Composition API du composant, appelée lors de l'instanciation du composant, utilisée pour définir des données et des méthodes réactives.
export default { setup() { const count = ref(0); return { count }; } }
2ref()
Créer une référence réactive pour encapsuler des types primitifs ou des objets.
const count = ref(0)
3computed()
Créer une valeur calculée à partir d'autres données réactives.
const doubledCount = computed(() => count.value * 2)
4reactive()
Créer un objet réactif, adapté aux objets ou aux tableaux.
const state = reactive({ count: 0 })
5readonly()
Créer des données réactives en lecture seule, interdisant toute modification.
const state = readonly({ count: 0 })
6watchEffect()
Créer un effet secondaire réactif qui suit automatiquement ses dépendances réactives associées.
watchEffect(() => { console.log(count.value) })
7watchPostEffect()
Un effet secondaire déclenché après la mise à jour du DOM.
watchPostEffect(() => { console.log('Post effect') })
8watchSyncEffect()
Exécuter les effets secondaires de manière synchrone lorsque les dépendances réactives changent.
watchSyncEffect(() => { console.log('Synchronized effect') })
9watch()
Utilisé pour observer les changements dans les données réactives ; vous pouvez spécifier des données réactives spécifiques ou des propriétés calculées.
watch(count, (newCount) => { console.log(newCount) })
10onWatcherCleanup()
Nettoyer l'observateur, appelé lorsque les données observées ne sont plus nécessaires.
watch(count, () => {}, onWatcherCleanup(() => { console.log('cleaned up') }))
11isRef()
Vérifier si une valeur est dereftype ref.
isRef(count)
12unref()
Déballer larefvaleur d'une ref.
unref(count)
13toRef()
Créer une ref réactive extraite d'un objet.
const countRef = toRef(state, 'count')
14toValue()
Déballerrefoureactiveune valeur de type ref.
toValue(count)
15toRefs()
Convertir chaque propriété d'un objet réactif en une ref indépendante.ref。
const { count } = toRefs(state)
16isProxy()
Vérifier si un objet est un objet proxy Vue.
isProxy(state)
17isReactive()
Vérifier si un objet est un objet réactif.
isReactive(state)
18isReadonly()
Vérifier si un objet est un objet réactif en lecture seule.
isReadonly(state)
19shallowRef()
Créer un objet réactif superficiel,refen ne rendant réactives que les propriétés de premier niveau de l'objet.
const state = shallowRef({ count: 0 })
20triggerRef()
Forcer le déclenchementrefla mise à jour de ref.
triggerRef(count)
21customRef()
Créer une ref réactive personnalisée, permettant aux développeurs de personnaliser le getter et le setter.
const count = customRef((track, trigger) => { let value = 0; return { get: () => value, set: (val) => { value = val; trigger() } } })
22shallowReactive()
Créer un objet réactif superficiel, où seules les propriétés de premier niveau de l'objet sont réactives.
const state = shallowReactive({ count: 0 })
23shallowReadonly()
Créez un objet réactif en lecture seule superficiel, où seules les propriétés de premier niveau de l'objet sont en lecture seule.
const state = shallowReadonly({ count: 0 })
24toRaw()
Obtenez l'objet brut d'un objet proxy.
const rawState = toRaw(state)
25markRaw()
Marquez un objet comme non proxyable, et Vue ignorera la gestion réactive pour cet objet.
const obj = markRaw({ count: 0 })
26effectScope()
Créez une nouvelle portée d'effet pour gérer les effets secondaires.
const scope = effectScope()
27getCurrentScope()
Obtenez la portée d'effet actuelle.
const scope = getCurrentScope()
28onScopeDispose()
Exécutez une fonction de nettoyage lorsque la portée d'effet est détruite.
onScopeDispose(() => { console.log('Scope disposed') })
29onMounted()
Hook de cycle de vie appelé lorsque le composant est monté.
onMounted(() => { console.log('Component mounted') })
30onUpdated()
Hook de cycle de vie appelé lorsque le composant est mis à jour.
onUpdated(() => { console.log('Component updated') })
31onUnmounted()
Hook de cycle de vie appelé lorsque le composant est démonté.
onUnmounted(() => { console.log('Component unmounted') })
32onBeforeMount()
Hook de cycle de vie appelé avant le montage du composant.
onBeforeMount(() => { console.log('Before mount') })
33onBeforeUpdate()
Hook de cycle de vie appelé avant la mise à jour du composant.
onBeforeUpdate(() => { console.log('Before update') })
34onBeforeUnmount()
Hook de cycle de vie appelé avant le démontage du composant.
onBeforeUnmount(() => { console.log('Before unmount') })
35onErrorCaptured()
Capturer les erreurs non gérées dans l'arbre des composants.
onErrorCaptured((err, instance, info) => { console.error(err) })
36onRenderTracked()
Hook déclenché lorsque des données réactives sont suivies pendant le rendu du composant.
onRenderTracked((event) => { console.log(event) })
37onRenderTriggered()
Hook déclenché lorsque des données réactives changent pendant le rendu du composant.
onRenderTriggered((event) => { console.log(event) })
38onActivated()
Hook de cycle de vie appelé lorsque le composant est activé (utilisé pourkeep-alivecomposant).
onActivated(() => { console.log('Component activated') })
39onDeactivated()
Hook de cycle de vie appelé lorsque le composant est désactivé (utilisé pourkeep-alivecomposant).
onDeactivated(() => { console.log('Component deactivated') })
40onServerPrefetch()
Hook pour le préchargement des données lorsque le composant est rendu côté serveur.
onServerPrefetch(async () => { await fetchData() })
41provide()
Fournir des dépendances aux composants descendants.
provide('key', value)
42inject()
Injecter des dépendances depuis les composants parents ou ancêtres.
const value = inject('key')
43hasInjectionContext()
Vérifier s'il existe actuellement un contexte d'injection.
hasInjectionContext()
44useAttrs()
Obtenir tous les attributs du composant, y compris les attributs HTML transmis au composant.
const attrs = useAttrs()
45useSlots()
Obtenir le contenu du slot du composant.
const slots = useSlots()
46useModel()
Obtenir lav-modelvaleur liée du composant actuel.
const modelValue = useModel()
47useTemplateRef()
Obtenir une référence à l'élément dans le template.
const templateRef = useTemplateRef('elementId')
48useId()
Obtenir un identifiant unique.
const uniqueId = useId()
Autres extensions