From Vue2 Master to Vue3 Noob
Tags: vue, webdev, compositionapi
Published: 2021-04-05 01:39:56

---
title: From Vue2 Master to Vue3 Noob
published: true
description: A tour of some of the main changes from vue2 to vue3
tags: vue, webdev,compositionAPI
cover_image: ![vue2vue3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7yoc5391looki0vud9zn.jpeg)
---
you can check the original post on my [blog](https://eaglewas.me/blog/en/vue2master-to-vue3noob) in both english and spanish

so I used to tell myself I was good at building webapps with vue, but then the vue3 nation attacked (yes, an avatar reference).
with this introduction to vue3, a lot of things changed, I like to think about it as the react hooks change but for vue, the main thing I consider that is a major and it's worth getting used to it and learn is the <span class="text-yellow-600 font-bold italic">Composition API</span> which I'll be talking more in detail while creating a simple webapp to display some pokemon data

## Setup()
Vue3 introduces a new component option called setup, which is the entrypoint for the composition API, it's important to know that the code written here is executed before the creation of the component therefore the **data, computed, and method options aren't available inside of it.**
The setup component options contains two parameters
- props
- context (which contains attrs, slots, emit)

In this example I'll be getting the pokemonId prop or if it doesn't exist I'll be assigning one randomly,
then I'll call the API to get the pokemon sprite,  the return of the setup options allows you to use those values on the template
```js
setup(props) {
    const pokemonId = props.pokemonId || Math.ceil(Math.random() * 500)
    const pokemonSprite = getPokemonData(pokemonId); //magic function that returns a sprite
    return {
        pokemonId,
        pokemonSprite
    }
}
```
after this we can just do this inside the template to show the sprite image:
```html
<template>
    <img :src="pokemonSprite" alt="pokemon sprite" />
</template>
```

## Ref() and Reactive()
Vue3 by default doesn't make every variable reactive, you have to define it yourself using the new 
<span class="text-yellow-600 font-bold italic">ref()</span>, <span class="text-yellow-600 font-bold italic">reactive()</span> methods

these methods are really similar, the main difference is that is recommended to use ref() on data types (ints, bools, strings, etc..) and to use reactive() on data structures (arrays, sets, json, etc...)

for example, if we want to add a button to randomize a pokemon sprite on click, we need to make the pokemonId prop reactive:
```js
import { ref } from 'vue'
setup(props) {
    let pokemon = ref({})
    const getPokemonData = async (pokemonId) => {
        const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${pokemonId}`)
        pokemon.value = await response.json();
    }
    getPokemonData(props.pokemonId);
    return {
        pokemon,
        getPokemonData
    }
},
methods: {
    randomize() {
        this.getPokemonData(Math.ceil(Math.random() * 500));
    }
}
```

and then in our template we can just do this:
```html
<template>
    <div v-if="pokemon.sprites">
        <img :src="pokemon.sprites.front_default" alt="pokemon sprite" />
        <button @click="randomize">Randomize</button>
    </div>
</template>
```

## Lifecycle hooks
Another new addition to vue3, is the ability to call lifecycle hooks **only inside the setup component option**, replacing all the other components options we used to have(mounted {}, created{}, etc..) with the new variants (onMounted(), onCreated(), etc..)
this makes the code more readable since in the setup, you'll be declaring all the initialization of your component in a single place

we can change our pokemon randomizer code to make use of the onMounted hook inside the setup

```js
import { ref, onMounted } from 'vue'
setup(props) {
    let pokemon = ref({})
    const getPokemonData = async (pokemonId) => {
        const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${pokemonId}`)
        pokemon.value = await response.json();
    }
    onMounted(getPokemonData(props.pokemonId));
    return {
        pokemon,
        getPokemonData
    }
},
```

## Script setup
Now that I understand how the setup worked, I wanted to go even further explorating the `<script setup>` proposal
after playing with it for a couple of minutes, I understood how awesome it is! the time saving and less code written are really good benefits of it, it adds a couple of new different syntax for props, but nothing to extreme, 
this is how the pokemon randomizer code looks like with the script setup:

```js
<script setup>
import { ref, onMounted } from 'vue'
const props = defineProps({
  pokemonId: Number,
});
let pokemon = ref({})
const getPokemonData = async (pokemonId) => {
    const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${pokemonId}`)
    pokemon.value = await response.json();
}
const randomize = () =>  {
    getPokemonData(Math.ceil(Math.random() * 500));
}
onMounted(getPokemonData(props.pokemonId));
```

you can check the source code in [here](https://github.com/eagleera/vue3pokemonexample)

Sources
- https://blog.logrocket.com/refactoring-your-vue-2-apps-to-vue-3/
- https://v3.vuejs.org/guide/composition-api-introduction.html
- https://github.com/vuejs/rfcs/pull/227