Vue composition api: Guia prático para alquimistas.
Tags: vue, computerscience, algorithms, javascript
Published: 2020-12-30 00:09:21

Bom dia, site.

Hoje venho compartilhar um pouco do conhecimento adquirido nas ultimas semanas estudando a nova api do vue, a ``VUE COMPOSITION API``.

Sumário:

[1. Introdução: Boas vindas, jovem mago;](#introducao)
[2. Setup(): O cérebro do componente;](#setup)
[2.1 JSX;](#setup)
[2.2 Capturando Props;](#props)
[2.3 Context;](#context)
[3. Reatividade: A lei da Alquimia;](#reatividade)
[3.1 Reactive;](#reactive)
[3.2 Ref;](#ref)
[3.3 Reactive ou ref?;](#reactiveorref)
[4. Computed: O watch que observa diferente;](#computed)
[5. ReadOnly: Simple;](#readonly)
[6. Watch: O olhar sanguinário do vigia;](#watch)
[7. Ciclos de vida;](#lifecycle)

####Introdução, O problema dos mixins.

<b id="introducao">Boas vindas, jovem mago.</b><br>
Primeiramente deve-se entender o processo que ocasionou o desenvolvimento da composition api. Apesar das inúmeras features da segunda versão do vue, <b>o mesmo ainda possuía uma defasagem problemática em relação ao encapsulamento de código de forma performática utilizando mixins</b>.

É provável que o instanciamento de dois ou mais mixins não possam ser utilizados de forma isócrona, por exemplo, se ambos mixins utilizam o método foo(), o método será interrompido pois o método remanescente irá sobrescrever o precedentemente.

Harmonizar centenas de funções em projetos que dependem de ser altamente escaláveis pode ser um grande problema, pois você deve refatorar o mixin e depois realizar o mesmo processo em todos os componentes que implementam o mesmo.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/aemdpn7bpmwqqri9lln6.png)

Esse é apenas um dos nêmesis que o composition api foi forjado para resolver, veremos mais nos próximos tópicos desse artigo. 

####Setup(): O cérebro do componente.

Considere o método <b id="setup">setup</b> como o cérebro do componente, pois é a partir do mesmo que iremos definir os demais métodos e instanciaremos nossas variáveis, não ficou muito claro ainda, não é mesmo? Sem problemas, veja a imagem abaixo:


![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/s6wp0787apzmvrw1l5l2.png)

Considerando o tempo de execução da aplicação, o método setup() se encontra no ciclo `beforeCreate()`.

Observe que o objeto mage não é reativo, veremos mais sobre reatividade no próximo capitulo.

Acessando as <b id="props">props</b> de um componente.

Podemos acessar as propriedades de um componente através do primeiro parâmetro de do método setup:



![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/l3rhqnk0izyb0f3rjivb.png)

*<b>Não force a desestruturação</b> das propriedades pois você perderá a reatividade e receberá um erro no console e seu componente não será montado*.

Para encerrar esse capítulo precisamos falar um pouco sobre o <b id="context">context</b>, que é o segundo parâmetro recebido por setup(), em suma, o context obtêm todo objeto de instancia previamente exibida pelo `this` da segunda versão do vue. 

*retorno fornecido pelo context:*
```
attrs: (...)
emit: (...)
expose: exposed => {…}
props: (...)
slots: (...)
```


Uma vez que setup() é chamado antes do contexto, o `this como conhecemos não está disponível`!

####<span id="reatividade">Reatividade: A lei da Alquimia.</span>

Considero essa a mudança mais considerável para a versão antecedente do vue, outrora, utilizávamos a propriedade `data` como mecanismo de definição de valores reativos.
 
Existem algumas formas de transformar uma variável comum, em uma variável reativa:

Utilizando <b id="reactive">reactive</b> , pegamos um objeto e retornamos um proxy reativo do original.

```
import { reactive } from 'vue'
  export default {
    setup() {
      const mage = reactive({
        type: 'fire',
        strong: 8
      })

      const changeTypeOfMage = () => mage.type = 'water'

      return {
        mage,
        changeTypeOfMage
      }
    }
  }
``` 

Nota-se que retornamos o método que muda o type do nosso objeto mage, uma vez que o método será utilizado dentro do jsx, como observamos nos capítulos anteriores.

Se você deseja transformar um tipo de dado primitivo em uma propriedade reativa, utilize o hook <b id="ref">ref</b>.

```
import { ref } from 'vue'
  export default {
    setup() {
      let isMage = ref(true)
      const notMage = () => isMage.value = !isMage.value;
      return {
        isMage,
        notMage
      }
    }
  }
```

<b id="reactiveorref" >Quando usar reactive e quando usar ref?</b>

Vamos para lei da alquimia geral, tenha pretensão de usar ref para tipos primitivos, como: String, Number, BigInt, Boolean, Symbol, Null e Undefined. Para objetos onde a teremos uma deep reactive, utilize reactive.

####Computed: O watch que observa diferente.

Assim como o <b id="computed">computed</b> da versão anterior, pense em uma variável que retorna uma função, a diferença dessa vez é que o computed do vue composition api retorna 2 métodos: o `get()` que retorna uma função com o dado imutável e não reativo, e o método `set()`, que consegue mutar essa regra e mudar os valores contidos no retorno do computed;

```
<template>
  <p>Name: {{mage.name}}</p>
  <p>Type: {{mage.type}}</p>
  <p>Strong: {{mage.strong}}</p>
  <p>Status: {{status}}</p>
  <button @click="enchant">enchant armor</button>
  <button @click="disenchant">disenchant armor</button>
</template>

<script>
<template>
  <p>Name: {{mage.name}}</p>
  <p>Type: {{mage.type}}</p>
  <p>Strong: {{mage.strong}}</p>
  <p>Status: {{status}}</p>
  <button @click="enchant">enchant armor</button>
  <button @click="poison">poison armor</button>
</template>

<script>
import { computed, reactive } from "vue";
export default {
  setup() {
    const mage = reactive({
      type: 'fire',
      strong: 4,
      name: 'Black Mage',
    })

    const status = computed({
      get: () => mage.strong > 7 ? 'stronger' : 'weak',
      set: (value) => mage.type = value
    })

    const enchant = () => mage.strong = mage.strong + 4
    const poison = () => {
      mage.strong = mage.strong - 4;
      status.value = 'poisoned'
    }

    return { mage, status, enchant, poison }
  },
};
</script>
```
Observe o caso acima, declaramos um objeto inferindo que ele seja uma mago e que possua tais atributos, o computed está ali para observar o nível de força de nosso mago e mudar seu status caso ele se torne fraco ou forte, para pegar esse detalhe utilizamos seu método `get()` como explicado acima, porem por default o status se torna imutável e não reativo, para isso utilizamos o `set()` definido no computed para atribuir um novo status ao nosso mago. Ainda ficou com alguma dúvida? copie e execute o código, verá que na prática irá fazer mais sentido!

####Readonly: Literalmente isso.

O hook <b id="readonly">readonly</b> pega um objeto (reativo ou simples) ou um ref e retorna um proxy somente leitura para o original. Um proxy somente leitura: qualquer propriedade aninhada acessada também será somente leitura.

####Readonly: Watch: O olhar sanguinário do vigia.

O <b id="watch">`watchEffect`</b> é uma novidade também, porem com grandes poderes vem grandes responsabilidades, a utilização watcheffect pode ter N aplicação uma vez que ela se transforma qualquer dado inferido no setup como um dado observável.

Considere o código construído no exemplo do computed, caso você queira observar a mudança constante do nível de força de nosso mago você adicionaria o código abaixo: 

```
watchEffect(() => console.log(mage.strong));
```
Comumente ao ciclo de vida do componente, o watchEffect é desfeito toda vez que nosso componente morre.

####Ciclos de vida.

Apesar da mudança de alguns nomes, grande parte dos hooks ainda possuem suas respectivas funções, exceto o setup() e `dois novos hooks`: `onRenderTracked` e `onRenderTriggered`.

| Antigo      | Novo  |
| :------------- | :----------: |
|  beforeCreate | setup()  | 
| created  | setup() |
| beforeMount  | onBeforeMount |  
| mounted  | onMounted |  
| beforeUpdate  | onBeforeUpdate |  
| updated  | onUpdated |  
| beforeDestroy  | onBeforeUnmount |  
| destroyed  | onUnmounted | 
| activated  | onActivated | 
| deactivated  | onDeactivated | 
| errorCaptured  | onErrorCaptured | 

-Como utilizar os hooks?

```
const Mage = {
  setup() {
    onMounted(() => {
      console.log('Drop!')
    })
    onUpdated(() => {
      console.log('New Level!')
    })
    onUnmounted(() => {
      console.log('Dead!')
    })
  }
}
```

Em minha concepção essa são as mudanças fundamentais realizadas na nova versão do vue, em breve postarei a parte 2 e nela irei explicar um pouco sobre injeção de dependência, vue3 com typescript, unity testes e alguns tips de reatividade.

Obrigado por ler até aqui, o objetivo desse post é deixar a sintaxe e esclarecer alguns pontos sobre o vue composition api, não deixe de entrar em contato ou escrever um comentário caso eu tenha errado em algum momento.



> PARTE 2: undefined
 


<a href="https://github.com/devneto">![image](https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white)</a>

<a href="https://www.instagram.com/dev.neto">![image](https://img.shields.io/badge/Instagram-E4405F?style=for-the-badge&logo=instagram&logoColor=white)</a>