Component vs View.
Tags: vue, javascript, frontend, architecture
Published: 2023-05-19 14:00:11

E aê Frontender, debugando muito código com console.log(❤️)?

No meu primeiro post aqui, venho falar sobre mais uma das dificuldades para nós, programadores, assim como dar bons nomes às nossas variáveis com significado e contexto, pode ser algo que leva tempo, os componentes e as views em um projeto front-end se encaixam muito bem nessa mesma situação, no sentido dos seus propósitos no projeto.

Você não precisa ir muito longe para encontrar projetos com componentes de umas 1000 linhas de código e cheios de regras mirabolantes que vão se comportar dependendo do que tu passa pelas propriedades ou dentro do componente.

Sobre componentes, na doc do Vue:

> Os componentes nos permitem dividir a interface do usuário em peças **independentes** e **reutilizáveis** e pensar em cada peça **isoladamente**. [Components Basics](https://vuejs.org/guide/essentials/component-basics.html)

## Componentes de contexto

Se no seu projeto tem vários componentes que fazem algo parecido com isso:

```js
[...]
if(isUser){
  await fetchUser()
} else {
  await fetchCompany()
}
[...]
```
Temos então, componentes de contexto, componentes dependentes de que a lógica de alguma forma diga se é um usuário comum ou empresa, logo, ele não é um componente independente.

Temos daí, dois contextos, o contexto de usuário e o de empresa, onde o ideal seria criar componentes que tenham contexto único, exemplo:

```vue
<!-- User Info -->
<UserInfo />
await fetchUser()

<!-- Company Info -->
<CompanyInfo />
await fetchCompany()

<!-- In view -->
[...]
<component :is="userOrCompany" />

if(isUser){
  this.userOrCompany = UserInfo
} else {
  this.userOrCompany = CompanyInfo
}
[...]
```

## Componentes genéricos, independentes

Os componentes independentes de contexto, geralmente cumprem um único papel, não dependem de lógica contextualizada para existirem, exemplo:

```vue
<!-- SInput -->
<SInput />

<!-- Inside -->
[...]
<input :type="inputType" />

props:{
 inputType:{
  type: String,
  default: () => 'text',
 }
}
[...]
```
Por default no html os inputs sem a propriedade type, são do tipo texto, nem precisaria do default na propriedade do vue, mas o fato é que, esse componente consegue simplesmente existir sem precisar que alguma lógica diga para ele, de como ele deve se apresentar.

## Componentes reutilizáveis

Eu particularmente já encontrei algo bem parecido com isso:

```vue
<ModalNewUser />
<ModalNewSettings />
<ModalNewCity />
```

Mas não tem nada de errado nisso, correto? Deixa explicar, os componentes modais tinham exatamente replicados os mesmos comportamentos de uma modal, de forma simples, todos tinham, title, body e actions.

O problema:

```vue
<!-- ModalNewUser -->
<div class="modal">
  <div class="title">
    Add New User
  </div>
  <div class="body">
    <!-- form -->
  </div>
  <div class="actions">
    <button>cancel</button>
    <button>add</button>
  </div>
</div>
[...]

<!-- ModalNewSettings -->
<div class="modal">
  <div class="title">
    Add New Settings
  </div>
  <div class="body">
    <!-- form -->
  </div>
  <div class="actions">
    <button>cancel</button>
    <button>add</button>
  </div>
</div>
[...]

<!-- Etc -->
```

Uma possível solução, para reutilização:

```vue
<!-- SModal -->
<SModal />

<!-- Inside -->
<div class="modal">
  <div class="title">
    <slot name="title"> {{ title }} </slot>
  </div>
  <div class="body">
    <slot name="body"> {{ body }} </slot>
  </div>
  <div class="actions">
    <slot name="actions">
      <button>cancel</button>
      <button>add</button>
    </slot>
  </div>
</div>

props:{
  title: {
   type: String,
   default: () => 'Confirm action?',
  },
  body: {
   type: String,
   default: () => 'Click, to confirm action',
  }
}
```
O código resumido do componente a cima, mostrar duas formas de customizar um componente sem replicar código comportamental próprio da modal, se pode simplesmente mudar o texto do título e corpo por propriedades, ou, por slots caso no corpo da modal se adicione um formulário ou algo do tipo.

## Componente isolado

Por si só um componente é um trecho de código isolado, seja ele aplicado à um contexto ou um componente genérico, o importante, no caso de componentes contextualizados, é isolar por contexto dando ao componente uma única responsabilidade no projeto.

## Conclusão

Você deve ter notado, que o foco maior foi nos Components, porque na realidade a View é quem vai encapsular todo o resto, é um pouco mais complexo que isso, é verdade, temos que ter cuidado em sempre isolar o máximo de código a fim de evitar muita lógica condicional na View tornando a manutenção complexa.