Apprendre Vue.js 3 - Jour 4 : Composition API

ericlecodeur

Eric Le Codeur

Posted on August 5, 2021

Apprendre Vue.js 3 - Jour 4 : Composition API

Si vous désirez plus de contenu francophone comme celui-ci, cliquer Follow ou suivez-moi sur Twitter


La composition API

Est une alternative à l'Option API et permet d'écrire notre code regroupé et plus naturellement, sans utiliser des propriétés/objects et sans utiliser le mot clé 'this.'

Méthode setup()

Tout le code de votre component se retrouvera dans cette méthode

<template>
</template>

<script>
  export default {
    setup() {
       ..code du component..
    }
  }
</script>
<style>
</style>
Enter fullscreen mode Exit fullscreen mode

À noter que la section template et style reste inchangé

Valeur de retour de la méthode setup()

Si vous désirez utiliser une variables ou une fonctions en dehors de la méthode setup(), dans le template par exemple, vous devrez obligatoirement la retourner dans la méthode return()

<template>
  {{ title }}
</template>

<script>
  export default {
    setup() {
      let title = 'My Title'

      return {
        title,
      }
    }
  }
</script>
Enter fullscreen mode Exit fullscreen mode

Props

Vous pouvez accéder au props de votre component avec le paramètre props

<script>
  export default {
    props: ['title']
    setup(props) {
      console.log(props.title)

      return {

      }
    }
  }
</script>
Enter fullscreen mode Exit fullscreen mode

Variables Réactive

Pour utiliser la directive v-model sur une variable. vous devez rendre cette variable réactive avec la fonction ref()

<template>
  <input v-model="title">
</template>

<script>
  import { ref } from 'vue'
  export default {
    setup() {
      let title = ref('My Title')

      return {
        title,
      }
    }
  }
</script>
Enter fullscreen mode Exit fullscreen mode

propriété .value

Pour modifier une variable réactive, déclaré avec ref(), vous devez utiliser sa propriété .value

<template>
  <input v-model="title">
</template>

<script>
  import { ref } from 'vue'
  export default {
    setup() {
      let title = ref('My Title')
      title.value  = 'Hello World'

      return {
        title,
      }
    }
  }
</script>
Enter fullscreen mode Exit fullscreen mode

Directive ref pour lier un élément HTML

La directive ref peut également être utilisé afin de créer un binding avec un élément html (en remplacement de this.$ref dans l'option API))

<input :ref="title" type="text" />
Enter fullscreen mode Exit fullscreen mode
<script>
import { ref } from 'vue'

export default {
  setup() {
    import { ref } from 'vue'

    const title = ref(null)

     return {
       title,
     }
  }
</script>
Enter fullscreen mode Exit fullscreen mode

reactive : une alternative à a la fonction ref

<template>
  <input v-model="state.title">
</template>

<script>
  import { reactive } from 'vue'
  export default {
    setup() {
      const state = reactive({
        title: 'My Title'
      }

      state.title  = 'Hello World'

      return {
        person,
      }
    }
  }
</script>
Enter fullscreen mode Exit fullscreen mode

À noter que la fonction reactive prend uniquement un object comme valeur (pas de string, number, etc.) et que contrairement à la fonction ref() vous ne devez pas utiliser la propriété .value pour retourner la valeur de la variable.

Combinaison de BeforeCreate et Created Lifecycle Hook

Pour exécuter du code lors de la création du component simplement placé du code directement dans setup()

<template>
  <input v-model="title">
</template>

<script>
  import { ref } from 'vue'
  export default {
    setup() {
      let title = ref('My Title')
      title.value  = 'Default value on creation'

      return {
        title,
      }
    }
  }
</script>
Enter fullscreen mode Exit fullscreen mode

onMounted

Permet d'exécuter du code lors de la création du component

<script>
export default {
  import { onMounted, ref } from 'vue'
  setup() {
    let products = ref(null)

    onMounted(async () => {
      const response = await fetch('https://fakestoreapi.com/products')
      products.value = await response.json() 
    })
}
</script>
Enter fullscreen mode Exit fullscreen mode

Emit

La fonction emit remplace $emit

<template>
  <button @click="save">save</button>
</template>

<script>
  import { ref } from 'vue'
  export default {
    setup(props, { emit } ) {
      const id = 12
      const save = function() {
        emit('onCLickEvent', id)
      } 
      return {
        save,
      }
    }
  }
</script>
Enter fullscreen mode Exit fullscreen mode

Utilisation du Store (Vuex)

La méthode this.$store n'étant pas disponible en mode composition API vous devez maitenant utiliser la méthode useStore()

<template>
  <input v-model="title">
  <button @click="saveTitle">save</button>
</template>

<script>
  import { ref } from 'vue'
  import { useStore ] from 'vuex'

  export default {
    setup() {
      let title = ref('My Title')
      const store = useStore()

      title.value  = store.state.title

      return {
        title,
        saveTitle: () => store.commit('save')
      }
    }
  }
</script>
Enter fullscreen mode Exit fullscreen mode

À noter que la fonction saveTitle est en faite une fonction. Retourner une fonction permet de ne pas exécuter le commit tout de suite mais bien seulement lors de l'appel de saveTitle

Les méthodes computed()

<script>
  import { ref, computed } from 'vue'
  import { useStore ] from 'vuex'

  export default {
    setup() {
      let title = ref('My Title')
      const store = useStore()

      title.value  = store.state.title

      return {
          title,
        count: computed(() => store.state.count)
      }
    }
  }
</script>
Enter fullscreen mode Exit fullscreen mode

La variable computed 'count' va être rafraichis seulement si la valeur du 'state.count' change.

Méthode Watch

Permet d'exécuter du code lors de la modification d'une variable

<script>
  import { ref, watch } from 'vue'
  import { useStore ] from 'vuex'

  export default {
    setup() {
      let title = ref('My Title')
      const store = useStore()

      watch(title, (new, old) => {
        console.log('The title have change')
      }

      return {
        title,
        count: computed(() => store.state.count)
      }
    }
  }
</script>
Enter fullscreen mode Exit fullscreen mode

Pour faire un watch sur plusieurs variable en même temps vous pouvez utiliser la fonction watchEffect()

watchEffect(() => {
  console.log(count, title)
}
Enter fullscreen mode Exit fullscreen mode

La fonction va s'exécuter à chaque modification de toutes les variables présente dans le watchEffect()

Utilisation de Router et Route

En mode composition API vous ne pouvez pas utiliser 'this.$router' et 'this.$route', vous devrez utiliser useRouter et useRoute

<script>
  import { useRouter, useRoute) from 'vue-router'

  export default {
    setup() {
      const router = useRouter()
      const route = useRoute()

      router.push({ name: 'Home' })

      console.log(route.path, route.params)

    }
  }
</script>
Enter fullscreen mode Exit fullscreen mode

'script setup'

Il est possible d'utiliser la syntax abrégé pour créer le code de votre composition API

<script setup>
  import { ref, watch } from 'vue'
  import { useStore ] from 'vuex'

  let title = ref('My Title')
  const store = useStore()

  watch(title, (new, old) => {
    console.log('The title have change')
  }
</script>
Enter fullscreen mode Exit fullscreen mode

À noter l'attribut 'script setup' permet de ne pas utiliser de méthode setup() et pas de return non plus. Ils sont géré automatiquement. Vue fait un return avec toutes les variables et fonctions définit dans le top level.

Props et emit avec attribut setup

<script setup">
  import{ defineProps, defineEmit, useContext } from 'vue'

  defineProps(['msg']);
  // or
  defineProps({
    title: String,
  })
  // or
  const props = defineProps({
    title: String,
  })
  // console.log(props.title)

  const emit = defineEmit(['handleClick'])
  const { slot, attrs } = useContext()
</script>
Enter fullscreen mode Exit fullscreen mode

Conclusion

Merci d'avoir lu cet article. Si vous désirez plus de contenu francophone comme celui-ci, cliquer Follow ou suivez-moi sur Twitter

💖 💪 🙅 🚩
ericlecodeur
Eric Le Codeur

Posted on August 5, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related