<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Emanuel Gonçalves</title>
    <description>The latest articles on DEV Community by Emanuel Gonçalves (@emanuelgsouza).</description>
    <link>https://dev.to/emanuelgsouza</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F171674%2Ff48d10a2-8918-4eda-b952-856d6ecb1410.jpg</url>
      <title>DEV Community: Emanuel Gonçalves</title>
      <link>https://dev.to/emanuelgsouza</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/emanuelgsouza"/>
    <language>en</language>
    <item>
      <title>Teste seus componentes com Vue Test Utils</title>
      <dc:creator>Emanuel Gonçalves</dc:creator>
      <pubDate>Fri, 10 Sep 2021 12:37:46 +0000</pubDate>
      <link>https://dev.to/codecasts/teste-seus-componentes-com-vue-test-utils-3lla</link>
      <guid>https://dev.to/codecasts/teste-seus-componentes-com-vue-test-utils-3lla</guid>
      <description>&lt;p&gt;Fala! Hoje gostaria de trazer o assunto de testes com Vue.js. Depois de alguns meses trabalhando na criação de uma biblioteca de componentes de maneira intensiva, e agora, trabalhando na migração do produto principal aqui da empresa, gostaria de compartilhar alguns pensamentos e opiniões a respeito de algumas abordagens de testes com Vue.js e o uso de bibliotecas que nos auxiliam na hora de implementá-los.&lt;/p&gt;

&lt;p&gt;O objetivo é poder discutir o uso do &lt;a href="https://vue-test-utils.vuejs.org/"&gt;Vue Test Utils&lt;/a&gt; e do &lt;a href="https://testing-library.com/docs/vue-testing-library"&gt;Vue Testing Library&lt;/a&gt;, vantagens e desvantagens de usar um ou outro e quem sabe, num terceiro momento, trazer o uso do &lt;a href="https://docs.cypress.io/guides/component-testing/introduction"&gt;Cypress Component Testing&lt;/a&gt;, que promete bastante.&lt;/p&gt;

&lt;p&gt;Antes de mais nada, você precisa saber que os códigos deste post estarão neste repositório no Github - &lt;a href="https://github.com/emanuelgsouza/vue2-testing-blog"&gt;vue2-testing-blog&lt;/a&gt;. Dá aquela força dando um &lt;em&gt;star&lt;/em&gt; no projeto e compartilhando.&lt;/p&gt;

&lt;p&gt;Sem mais delongas, vamos ao conteúdo de hoje. Como testar nossos componentes Vue.js com Vue Test Utils!&lt;/p&gt;




&lt;p&gt;Primeiramente, vou pular a parte da instalação do Vue Test Utils (daqui para a frente vou chamá-lo de &lt;strong&gt;VTU&lt;/strong&gt;), pois normalmente se você inicia um projeto com o &lt;a href="https://cli.vuejs.org/"&gt;Vue CLI&lt;/a&gt; e escolhe entre as opções, que irá ter testes unitários, você vai perceber que este pacote será instalado por padrão. Porém, caso você precise de um guia para a instalação, você pode conferir a seção &lt;a href="https://vue-test-utils.vuejs.org/installation/#installation"&gt;"Instalação" na documentação oficial&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conhecendo um pouco do VTU
&lt;/h2&gt;

&lt;p&gt;Quando vamos testar nossos componentes Vue.js, precisamos, ao menos, executar duas tarefas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Buscar elementos dentro do componente&lt;/li&gt;
&lt;li&gt;Interagir com esses elementos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essas duas tarefas acima tem como objetivo testar se, dado uma interação com um componente, ele executa o que a gente espera dele. Vamos a um exemplo extraído da &lt;a href="https://vue-test-utils.vuejs.org/guides/#getting-started"&gt;documentação do VTU&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// nosso componente Counter&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;div&amp;gt;
      &amp;lt;button @click="count++"&amp;gt;Add up&amp;lt;/button&amp;gt;
      &amp;lt;p&amp;gt;Total clicks: {{ count }}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// nossa suíte de testes&lt;/span&gt;
&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;increments counter value on click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// busca elementos para interação&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;p&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// executa uma asserção para ter um valor inicial&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;toContain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Total clicks: 0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// interage com um elemento&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// testa se ocorre o resultado esperado&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;toContain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Total clicks: 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como você pode ver, executamos as duas tarefas e assim testamos o nosso componente de maneira satisfatória.&lt;/p&gt;

&lt;p&gt;Você pode encontrar mais informações sobre essa biblioteca no seu &lt;a href="https://vue-test-utils.vuejs.org/guides/#getting-started"&gt;site oficial&lt;/a&gt; e encontrar um conjunto de boas práticas no &lt;a href="https://lmiller1990.github.io/vue-testing-handbook/"&gt;Vue Testing Handbook&lt;/a&gt;, criado pelo autor do VTU.&lt;/p&gt;




&lt;p&gt;Depois dessa breve introdução, gostaria de compartilhar um pouco das minhas reflexões com relação à essa biblioteca. Já gostaria de adiantar que &lt;strong&gt;são minhas opiniões&lt;/strong&gt; depois de algum tempo usando bastante ela, seja no contexto de uma biblioteca de componentes, seja no contexto de uma aplicação real em construção.&lt;/p&gt;

&lt;h3&gt;
  
  
  Biblioteca oficial para testes
&lt;/h3&gt;

&lt;p&gt;Uma das coisas que mais incomodam quando vamos usar bibliotecas, plugins ou qualquer outra coisa em conjunto com nosso framework e estamos num processo de migração deste é o suporte que tais pacotes de terceiros irão ter com o framework que estamos utilizando.&lt;/p&gt;

&lt;p&gt;Sem dúvida, uma das melhores partes de se usar o VTU é que você vai estar usando uma ferramenta que é mantida pelo &lt;em&gt;core team&lt;/em&gt; do Vue.js. Isso significa que qualquer alteração no Vue.js terá impactos e "rapidamente" será propagado para o VTU.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interação com o componente a baixo nível
&lt;/h3&gt;

&lt;p&gt;Aqui vem uma questão polêmica: &lt;strong&gt;o que seria um teste unitário no contexto de aplicações componentizadas que temos hoje em dia?&lt;/strong&gt; Seria testar uma funcionalidade específica do meu sistema? Seria testar apenas um componente específico, isoladamente?&lt;/p&gt;

&lt;p&gt;Se sua resposta a última pergunta foi sim, o VTU é perfeito para você. Ao usarmos a função &lt;code&gt;mount&lt;/code&gt;, ela retorna uma instância de um componente, e assim podemos fazer um genuíno teste unitário caixa branca, pois podemos trabalhar com um componente a baixo nível e testar seu comportamento esperado nos mínimos detalhes.&lt;/p&gt;

&lt;p&gt;Mas, o que eu quero dizer com trabalhar com um componente no baixo nível?&lt;/p&gt;

&lt;p&gt;Se lembra que eu comentei que a função &lt;code&gt;mount&lt;/code&gt; retorna uma instância do componente? Por essa instância, eu tenho acesso as propriedades do meu componente (&lt;code&gt;data&lt;/code&gt;, &lt;code&gt;computeds&lt;/code&gt; e &lt;code&gt;props&lt;/code&gt;), bem como aos métodos dele. Sendo assim, imagine que meu componente tenha a seguinte estrutura:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// omitindo o template de propósito&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;

  &lt;span class="na"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;canSave&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isNotEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isNotEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isNotEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;isNotEmpty&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora eu quero testar que, se eu alterar o &lt;code&gt;model.name&lt;/code&gt;, e o &lt;code&gt;model.last_name&lt;/code&gt;, a computed &lt;code&gt;canSave&lt;/code&gt; ainda precisa ser &lt;code&gt;false&lt;/code&gt;, pois ainda não tenho um valor para &lt;code&gt;model.position&lt;/code&gt;. E eu consigo fazer isso sem muito esforço:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ignorando importação e montagem do componente&lt;/span&gt;
&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should keep the canSave computed as false even if name and last_name are filled&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;last_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;canSave&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eu também posso testar separadamente meu método &lt;code&gt;isNotEmpty&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should return the correct values for the vm.isNotEmpty() method&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isNotEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isNotEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isNotEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como consequência dessa interação a baixo nível, eu posso não testar a interação do meu usuário com o componente que eu estou testando. Um exemplo: imagine que você tem um componente de login que possui um método &lt;code&gt;login&lt;/code&gt; (bem criativo 😅). Você pode testar o método &lt;code&gt;login&lt;/code&gt; separadamente. Porém, eu acredito ser melhor testar a interação do usuário com esse método, por exemplo, testando se ao clicar no botão de Login, o método &lt;code&gt;login&lt;/code&gt; é chamado e executa a chamada à API com os parâmetros esperados.&lt;/p&gt;

&lt;p&gt;Uma outra consequência dessa interação a baixo nível é que se torna um pouco complexo usar o VTU para realizar buscas por elementos dentro do componente.&lt;/p&gt;

&lt;p&gt;Pegue como exemplo, este &lt;a href="https://github.com/emanuelgsouza/vue2-testing-blog/blob/main/src/components/Form.vue"&gt;simples componente de formulário&lt;/a&gt;. Imagine que eu precise testar o preenchimento de cada campo do formulário e ao final, precise clicar no botão de Salvar e esperar que o componente emita o que espero dele.&lt;/p&gt;

&lt;p&gt;Imaginou? Uma possível solução seria essa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should properly fill the model data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expectedModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;front&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[data-testid="form-name"] input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[data-testid="form-last_name"] input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[data-testid="form-position"] select&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;option&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setSelected&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expectedModel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[data-testid="btn-save"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;emitted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;save&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expectedModel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui eu uso &lt;code&gt;data-testids&lt;/code&gt; - uma &lt;a href="https://docs.cypress.io/guides/references/best-practices#Selecting-Elements"&gt;boa prática para desacoplar seus testes do código em si&lt;/a&gt; - para facilitar essa busca, porém, este problema nos leva a pelo menos dois pontos negativos ao usarmos o VTU.&lt;/p&gt;

&lt;h3&gt;
  
  
  Não é fluído testar componentes complexos
&lt;/h3&gt;

&lt;p&gt;Uma das minhas maiores dores com o VTU é buscar os elementos para interação, porém, eu preciso reconhecer que isso é uma característica da biblioteca. Ao mesmo tempo que é fácil buscar um componente filho na minha instância e interagir com ele, meu código de teste fica verboso e bastante acoplado à implementação.&lt;/p&gt;

&lt;p&gt;Em outras palavras, eu só tenho duas possibilidades de buscar elementos no meu componente: usando um seletor HTML (método &lt;a href="https://vue-test-utils.vuejs.org/api/wrapper/#find"&gt;find&lt;/a&gt; e afins) ou buscando pelo componente em si (usando o método &lt;a href="https://vue-test-utils.vuejs.org/api/wrapper/#findcomponent"&gt;findComponent&lt;/a&gt; e afins).&lt;/p&gt;

&lt;p&gt;Porém, você talvez concorde que estar acoplado a implementação neste caso não é ruim, na verdade é esperado, pois como estou testando &lt;em&gt;"unitariamente"&lt;/em&gt; meu componente, é esperado que eu saiba nos mínimos detalhes como ele funciona, e queira garantir através dos testes seu funcionamento.&lt;/p&gt;

&lt;h3&gt;
  
  
  É difícil testar acessibilidade
&lt;/h3&gt;

&lt;p&gt;Não é impossível verificar questões de acessibilidade quando usamos o VTU, porém, a biblioteca não encoraja uma abordagem de testes unitários/de integração que ao mesmo tempo, testem questões de acessibilidade.&lt;/p&gt;

&lt;p&gt;Um exemplo de teste de acessibilidade é verificar se os meus itens de formulários estão devidamente "rotulados", ou seja, se existem labels que os identificam. Com VTU isso é um pouco complexo. Eu precisaria saber o &lt;code&gt;id&lt;/code&gt; de cada elemento, e verificar se existe uma label com o correspondente atributo &lt;code&gt;for&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Em um outro momento veremos que existe uma outra biblioteca de testes que provê uma série de queries que trazem fluidez na hora que estamos criando nossos testes, e ao mesmo tempo, encoraja em pensarmos um pouco sobre acessibilidade na criação de nossos componentes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Resumindo
&lt;/h2&gt;

&lt;p&gt;Se você está a procura de uma biblioteca de auxílio nos testes unitários dos seus componente Vue.js, sem dúvida, o VTU é uma excelente alternativa, pois ele te dará um controle refinado para a criação dos seus testes.&lt;/p&gt;

&lt;p&gt;Todavia, é necessário deixar claro que caso o seu componente seja um pouco complexo e tenha interações com outros componentes, será um pouco trabalhoso criar seus testes com o VTU.&lt;/p&gt;

&lt;h2&gt;
  
  
  Aonde se aprofundar mais?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;a href="https://vue-test-utils.vuejs.org/"&gt;documentação do VTU&lt;/a&gt; é sucinta e direta ao ponto, comece por ela.&lt;/li&gt;
&lt;li&gt;Se está a procura de uma abordagem mais "mão na massa", não deixe de conferir o &lt;a href="https://lmiller1990.github.io/vue-testing-handbook/"&gt;Handbook do VTU&lt;/a&gt;, que traz alguns cases e algumas boas práticas na criação de testes com o VTU.&lt;/li&gt;
&lt;li&gt;Nas minhas pesquisas eu encontrei &lt;a href="https://github.com/dekadentno/vue-unit-testing-cheat-sheet"&gt;este Cheatsheet&lt;/a&gt; que achei bem interessante. Pode servir como uma referência.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Espero que este post tenha sido útil para você e que ele possa ter trazido algumas reflexões a respeito dessa excelente biblioteca de testes com Vue.js.&lt;/p&gt;

&lt;p&gt;Até a próxima.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>tests</category>
    </item>
    <item>
      <title>Conheça o que são as siglas CSR, SSR e SSG</title>
      <dc:creator>Emanuel Gonçalves</dc:creator>
      <pubDate>Fri, 27 Aug 2021 12:26:52 +0000</pubDate>
      <link>https://dev.to/codecasts/conheca-o-que-sao-as-siglas-csr-ssr-e-ssg-144e</link>
      <guid>https://dev.to/codecasts/conheca-o-que-sao-as-siglas-csr-ssr-e-ssg-144e</guid>
      <description>&lt;p&gt;Quando falamos de Nuxt, Next e outras ferramentas, geralmente encontramos algumas siglas difíceis de entender num primeiro momento: CSR, SSG e SSR. E juntamente com elas, surgem alguns questionamentos: Qual a diferença entre renderizar minha aplicação no lado do cliente ou no lado do servidor? Por qual motivo, geralmente, é recomendado eu fazer o uso da pré-renderização?&lt;/p&gt;

&lt;p&gt;O objetivo deste post é explicar os conceitos de &lt;em&gt;Client Side Rendering&lt;/em&gt; (CSR), &lt;em&gt;Static Site Generation&lt;/em&gt; (SSG) e &lt;em&gt;Server Side Rendering&lt;/em&gt; (SSR) elucidando tais questões, apresentando suas vantagens e desvantagens e alguns casos de uso.&lt;/p&gt;

&lt;p&gt;Antes de entrarmos nos conceitos, segue abaixo uma pequena relação de algumas ferramentas no mercado para a implementação destas técnicas em seu framework de escolha:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://angular.io/guide/universal"&gt;Angular Universal&lt;/a&gt; - ecossistema Angular&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nextjs.org/"&gt;Next&lt;/a&gt; - ecossistema React&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nuxtjs.org/"&gt;Nuxt&lt;/a&gt; - ecossistema Vue.js&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://sapper.svelte.dev/"&gt;Sapper&lt;/a&gt; - ecossistema Svelte&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Client-Side Rendering (CSR)
&lt;/h2&gt;

&lt;p&gt;É um formato de renderização em que a parte de renderização do conteúdo é feito no lado do cliente (browser). A tecnologia que mais utiliza esta técnica é a &lt;a href="https://imasters.com.br/front-end/por-que-utilizamos-single-page-applications-spa"&gt;Single Page Application&lt;/a&gt;. Neste formato, o servidor é responsável apenas por entregar os &lt;em&gt;assets&lt;/em&gt; necessários para a aplicação, mas o HTML não é servido com o seu conteúdo preenchido. Isso fica a cargo do browser.&lt;/p&gt;

&lt;p&gt;Toda SPA faz o trabalho de renderização no lado do cliente, mas nem toda aplicação que faz esse trabalho é uma SPA. Explico: antigamente, era comum o uso da técnica &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/Guide/AJAX"&gt;AJAX&lt;/a&gt; para a requisição de informações do servidor e exibição dessas mesmas informações para o cliente. Como essas informações eram exibidas? Através de manipulação do DOM, seja com jQuery ou outra biblioteca. O ponto é: tais aplicações não eram uma SPA (principalmente porque o roteamento da aplicação ainda era no servidor), apesar de executarem um trabalho de renderização no lado do cliente.&lt;/p&gt;

&lt;p&gt;Para saber mais sobre SPAs, confira o post &lt;a href="https://blog.codecasts.com.br/single-page-applications-onde-vivem-e-o-que-comem-4fc9a44f3de"&gt;Single Page Applications: Onde vivem e o que comem&lt;/a&gt; escrito por [Vinicius Reis]&lt;/p&gt;

&lt;h2&gt;
  
  
  Server-Side Rendering (SSR)
&lt;/h2&gt;

&lt;p&gt;É um formato de renderização de páginas já bastante conhecido. Como o nome diz, é uma renderização do lado do servidor. Desta forma, haverá a necessidade de uma estrutura no servidor responsável não apenas por servir os &lt;em&gt;assets&lt;/em&gt;, mas também por gerar as páginas HTML já completas, com o conteúdo populado. As ferramentas citadas possuem em seu &lt;em&gt;core&lt;/em&gt; tal funcionalidade, geralmente com um servidor em Node.js.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quais problemas o SSR resolve?
&lt;/h3&gt;

&lt;p&gt;Primeiramente, &lt;strong&gt;questões relacionadas a SEO&lt;/strong&gt; (Search Engine Optimization). Como numa SPA a renderização é feita no browser, e alguns &lt;a href="https://www.cloudflare.com/pt-br/learning/bots/what-is-a-web-crawler/"&gt;&lt;em&gt;web crawlers&lt;/em&gt;&lt;/a&gt; não tem capacidade de executar código JavaScript, apenas HTML, o &lt;em&gt;web crawler&lt;/em&gt; captura uma página com praticamente nenhuma informação semântica, o que é ruim para o SEO.&lt;/p&gt;

&lt;p&gt;Segundo, há as &lt;strong&gt;questões relacionadas a performance&lt;/strong&gt;. Uma página com o HTML com o conteúdo necessário já servido é bem melhor do que você ter este mesmo conteúdo em um JavaScript que será baixado, &lt;em&gt;parseado&lt;/em&gt; e executado em um momento posterior. Não só isso, em um &lt;a href="https://www.cetic.br/pt/publicacao/pesquisa-sobre-o-uso-das-tecnologias-de-informacao-e-comunicacao-nos-domicilios-brasileiros-tic-domicilios-2019/"&gt;contexto em que as pessoas usam mais os seus smartphones do que seus computadores para ter acesso a informação na internet&lt;/a&gt;, ter uma menor quantidade de código JavaScript é melhor. Lembre-se: performance também é uma métrica para a experiência do usuário.&lt;/p&gt;

&lt;p&gt;Porém, o SSR possui um questão na sua implementação: ele exige um servidor que execute a sua aplicação e sirva o código HTML. Atualmente, existem inúmeras formas gratuitas para se fazer isso, com um certo limite, como no caso da &lt;a href="https://vercel.com/"&gt;Vercel&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Static Site Generation (SSG)
&lt;/h2&gt;

&lt;p&gt;Você pode encontrar este mesmo conceito como &lt;strong&gt;pré-render&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;É um formato de renderização em que as páginas da aplicação são renderizadas na fase de build da aplicação e com isso, é possível usar qualquer servidor de páginas estáticas (Vercel, Netlify, Github Pages...) para disponibilizar seu conteúdo.&lt;/p&gt;

&lt;p&gt;Existem algumas ferramentas que são focados nesse tipo de formato, como o &lt;a href="https://www.gatsbyjs.com/"&gt;Gatsby&lt;/a&gt; para o React e o &lt;a href="https://gridsome.org/"&gt;Gridsome&lt;/a&gt; para Vue.js.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A performance&lt;/strong&gt;, neste formato, &lt;strong&gt;é superior ao do SSR&lt;/strong&gt; pelo fato de que não há um trabalho de renderização das páginas por demanda em algum servidor. Todas as páginas HTML da sua aplicação já foram populadas com as informações necessárias.&lt;/p&gt;

&lt;p&gt;Porém, há uma ressalva a ser feita: &lt;strong&gt;o tempo de build&lt;/strong&gt;. Em algumas aplicações, geralmente blogs, há uma quantidade enorme de conteúdo. Dessa forma, se toda a alteração feita em uma página exigir que todas as outras páginas sejam novamente geradas, isso leva a aumento no tempo de build. O Gatsby, por exemplo, já possui uma solução para esse problema através de &lt;a href="https://www.gatsbyjs.com/blog/2020-04-22-announcing-incremental-builds/"&gt;builds incrementais&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  É possível combinar estas técnicas?
&lt;/h2&gt;

&lt;p&gt;Sim, e geralmente se você está usando o Nuxt ou Next, você já combina elas. Por exemplo, com o &lt;a href="https://nuxtjs.org/docs/2.x/concepts/static-site-generation"&gt;SSG no Nuxt&lt;/a&gt;, ao acessar a primeira página, toda a navegação e renderização continuará seguindo pelo lado do cliente. Isso é positivo pelo fato de que não será necessário, uma vez carregado o site, buscar por novas páginas no servidor.&lt;/p&gt;

&lt;p&gt;Um outro caso de combinação é usando o Next, em que é possível ter uma renderização híbrida da página, com partes dela sendo pré-renderizadas e outras sendo renderizadas no browser. Ou ainda, no mesmo projeto, possuir páginas pré-renderizadas e outras renderizadas no servidor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Qual escolher?
&lt;/h2&gt;

&lt;p&gt;Depende do seu objetivo e propósito. Geralmente, para sites de conteúdo como blogs, uma pré-renderização das páginas (SSG) pode ser uma boa escolha por questões de SEO e performance, haja vista que o conteúdo não muda com muita frequência. Em casos de aplicações complexas, geralmente tem-se optado pelo uso de SPAs, e consequentemente de CSG, também por questões de performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Espero que este texto possa ter servido para esclarecer suas dúvida. Se possui algum comentário, não deixe de fazê-lo. Até a próxima!&lt;/p&gt;

&lt;h2&gt;
  
  
  Para saber mais sobre o assunto:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/web/updates/2019/02/rendering-on-the-web"&gt;Post da Google sobre os formatos de renderização na Web&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.angular-university.io/angular-universal/"&gt;Documentação do Angular Universal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/X3W-YFe2_io"&gt;Vídeo do Willian Justen sobre o assunto&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nextjs.org/docs/basic-features/pages"&gt;Documentação do Next.js sobre Pages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://imasters.com.br/front-end/por-que-utilizamos-single-page-applications-spa"&gt;Texto do IMasters explicando a diferença entre Multi/Single Page Applications&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.gatsbyjs.com/blog/2020-04-22-announcing-incremental-builds/"&gt;Post oficial da equipe do Gatsby sobre os Incremental Builds&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>rendering</category>
    </item>
    <item>
      <title>Grid para layout, flexbox para componentes</title>
      <dc:creator>Emanuel Gonçalves</dc:creator>
      <pubDate>Fri, 26 Jun 2020 12:34:17 +0000</pubDate>
      <link>https://dev.to/codecasts/grid-para-layout-flexbox-para-componentes-gb3</link>
      <guid>https://dev.to/codecasts/grid-para-layout-flexbox-para-componentes-gb3</guid>
      <description>&lt;p&gt;&lt;span&gt;Imagem de fundo por &lt;a href="https://unsplash.com/@halacious?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Halacious&lt;/a&gt; on &lt;a href="/s/photos/layout?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Compartilho com você a tradução autorizada deste excelente artigo escrito por &lt;a href="https://twitter.com/shadeed9" rel="noopener noreferrer"&gt;Ahmad Shadeed&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Título original - &lt;a href="https://ishadeed.com/article/grid-layout-flexbox-components/" rel="noopener noreferrer"&gt;Grid for layout, Flexbox for components&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Meu irmão é recém-formado em engenharia da computação e ele está atualmente finalizando seu estágio em desenvolvimento front-end. Ele aprendeu sobre CSS grid e flexbox, mas eu notei um padrão que eu vi muito na web. Ele não conseguia decidir quando usar grid ou flexbox. Por exemplo, ele usou CSS grid para fazer o layout do cabeçalho de um site e mencionou que o processo não foi tranquilo, pois ele brincava com a propriedade &lt;code&gt;grid-column&lt;/code&gt; e tentava ajustá-la até se parecer com o design.&lt;/p&gt;

&lt;p&gt;Para ser sincero, não gosto disso, e também pesquisei sobre um recurso que ele pode usar para aprender as diferenças entre grid e flexbox, com exemplos de ambos, mas não consegui encontrar nenhum. Decidi escrever um artigo profundo que cubra tudo sobre aquele tópico. Espero que você ache claro!&lt;/p&gt;

&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Antes de entrar de cabeça nos conceitos e exemplos, eu quero me certificar que você entende a diferença entre CSS grid e flexbox. CSS grid é um módulo multi-dimensional de layout, que significa que ele possui colunas e linhas. Flexbox pode dispor seus itens filhos como colunas ou linhas, mas não ambos.&lt;/p&gt;

&lt;p&gt;Se você não conhece CSS grid e flexbox, eu recomendo ler &lt;a href="https://ishadeed.com/article/learn-box-alignment/" rel="noopener noreferrer"&gt;este artigo visual&lt;/a&gt;. Se você os conhece, que legal, vamos mergulhar nas diferenças entre eles e quando usar cada um e o porquê.&lt;/p&gt;

&lt;h2&gt;
  
  
  A diferença entre Grid e Flexbox
&lt;/h2&gt;

&lt;p&gt;Deixe-me ser claro a respeito disso, não há uma maneira direta de decidir entre CSS grid e flexbox. Além disso, não há uma forma &lt;strong&gt;correta&lt;/strong&gt; e &lt;strong&gt;incorretá&lt;/strong&gt; de usá-los. Este artigo é um tipo de guia que &lt;strong&gt;recomenda&lt;/strong&gt; usar uma técnica para um específico caso de uso. Eu explicarei o conceito geral, e então ir aos exemplos, e o resto é você que explora e experimenta mais.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Flexbox wrapper */&lt;/span&gt;
&lt;span class="nc"&gt;.wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Grid wrapper */&lt;/span&gt;
&lt;span class="nc"&gt;.wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fgrid-vs-flexbox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fgrid-vs-flexbox.png" alt="Imagem mostrando a diferença entra Flexbox e grid em uma linha"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Você notou alguma coisa? O Flexbox apresenta uma lista in-line de elementos, enquanto o CSS grid os torna os transforma em um grid de colunas e linhas. Flexbox está alinhando o alinhamento em uma linha. Isso pode ser uma coluna, se quisermos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Flexbox wrapper */&lt;/span&gt;
&lt;span class="nc"&gt;.wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fgrid-vs-flexbox-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fgrid-vs-flexbox-1.png" alt="Imagem mostrando a diferença entra Flexbox e grid em colunas"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Como decidir qual usar
&lt;/h2&gt;

&lt;p&gt;Decidir entre CSS grid e flexbox pode ser um pouco difícil (às vezes), especialmente se você é novo em CSS. Eu posso ouvir você! Aqui estão algumas perguntas iniciais que eu faço ao escolher entre eles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Como os itens filho do componente são exibidos? Em linha ou em colunas e linhas?&lt;/li&gt;
&lt;li&gt;Como o componente deve funcionar em diferentes tamanhos de tela?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Na maioria das vezes, se o componente que você está vendo tiver todos os itens filhos exibidos em linha, provavelmente o flexbox é a melhor solução. Considere o seguinte exemplo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fdecide-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fdecide-1.png" alt="Imagem mostrando que um componente possui dois filhos dispostos em linha"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Contudo, se você ver colunas e linhas, o CSS grid é a solução para o seu caso.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fdecide-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fdecide-2.png" alt="Imagem mostrando que há um layout com 3 colunas e duas linhas"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora que expliquei a principal diferença entre eles, passemos a exemplos mais específicos e vejamos como decidir.&lt;/p&gt;

&lt;h2&gt;
  
  
  Casos de uso e exemplos
&lt;/h2&gt;

&lt;p&gt;Na seção a seguir, discutirei em detalhes sobre os diferentes casos de uso para flexbox e grid.&lt;/p&gt;

&lt;h3&gt;
  
  
  CSS Grid
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Main e Sidebar
&lt;/h4&gt;

&lt;p&gt;Quando você tem uma barra lateral e seção principal (&lt;code&gt;main&lt;/code&gt;), o CSS Grid é uma solução perfeita para construí-los. Considere a seguinte modelo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fgrid-use-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fgrid-use-1.png" alt="Imagem que mostra duas seções, uma com uma barra lateral à esquerda e a seção principal à direita"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aqui está como eu faria isso em CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"wrapper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;aside&amp;gt;&lt;/span&gt;Sidebar&lt;span class="nt"&gt;&amp;lt;/aside&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;Main&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;800px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200px&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;grid-gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nt"&gt;aside&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;align-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se &lt;code&gt;align-self&lt;/code&gt; não for usado para o elemento &lt;code&gt;aside&lt;/code&gt;, a altura dele será igual ao do elemento &lt;code&gt;main&lt;/code&gt;, não importa o tamanho do conteúdo.&lt;/p&gt;

&lt;h4&gt;
  
  
  Cards em Grid
&lt;/h4&gt;

&lt;p&gt;Conforme discutido no início do artigo, o CSS grid é auto-explicativo a partir do nome, portanto, usá-lo para criar uma grade de cartões é um uso perfeito dele.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fgrid-use-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fgrid-use-2.png" alt="Imagem mostrando um grid de cards com 3 colunas e duas linhas"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aqui está como eu implementaria o layout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto-fit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="py"&gt;grid-gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A largura da coluna será de pelo menos &lt;code&gt;200px&lt;/code&gt;, e se o espaço não for suficiente, ele irá colocar os cards em uma nova linha. Vale ressaltar que o código acima pode causar rolagem horizontal se a largura do &lt;em&gt;viewport&lt;/em&gt; for menor que &lt;code&gt;200px&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Uma solução simples é adicionar a definição de grid somente quando a largura do &lt;em&gt;viewport&lt;/em&gt; for suficiente. Veja abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;800px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto-fit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="py"&gt;grid-gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Layout de seção
&lt;/h4&gt;

&lt;p&gt;No design a seguir, podemos usar o grid duas vezes, o primeiro uso é dividir a área em outras duas áreas (a barra lateral "Contact us", e o formulário) e o segundo uso é no próprio grid do formulário.&lt;/p&gt;

&lt;p&gt;Não consigo enfatizar o quanto CSS grid é perfeito para isso. Aqui está como fazer no CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;800px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200px&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.form-wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;grid-gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.form-message&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="nc"&gt;.form-button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;grid-column&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* deixe que eles tomem toda a largura */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este exemplo é emprestado do &lt;a href="https://webdesign.tutsplus.com/tutorials/how-to-build-web-form-layouts-with-css-grid--cms-28776" rel="noopener noreferrer"&gt;meu artigo&lt;/a&gt; na Envanto sobre a construção de layouts para formulários web com CSS grid. Eu recomendo que você leia.&lt;/p&gt;

&lt;h3&gt;
  
  
  CSS Flexbox
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Navegação do website
&lt;/h4&gt;

&lt;p&gt;90% das vezes, a navegação do website deverá ser feita com Flexbox. O padrão mais comum é ter a logo à esquerda e a navegação à direita. Isso é perfeito para flexbox.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-1.png" alt="Imagem mostrando uma simples nagevação, com a logo à esquerda e o menu à direita"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No exemplo acima, tudo que você precisa definir é o seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.site-header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-wrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O mesmo conceito também pode funcionar no seguinte design também.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-2.png" alt="Imagem mostrando a mesma navegação anterior, porém, com um maior espaçamento no elemento final"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note como a estrutura de navegação ficou um pouco diferente, mas o espaçamento entre os itens ainda é feito com a propriedade &lt;code&gt;justify-content&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Lista de ações
&lt;/h4&gt;

&lt;p&gt;Quando você ouve falar de uma lista, a primeira coisa que você pensa é uma lista vertical. No entanto, uma lista pode ser exibida em linha, então eu só queria ter certeza de que isso está claro.&lt;/p&gt;

&lt;p&gt;Um exemplo de uma lista de ações é algo que podemos pegar emprestado do Facebook ou Twitter. A lista de ações consiste em botões de ação que o usuário pode executar. Veja as imagens abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-3.png" alt="Imagem mostrando uma lista de ação do Facebook e do Twitter"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como você vê, os itens são exibidos um ao lado do outro e são distribuídos horizontalmente. Flexbox é perfeito para isso! Esse é um dos principais usos dele.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.actions-list&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.actions-list__item&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* expande os items para que tomem todo o espaço disponível igualmente entre eles */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Outra variação disso é um botão de ação de uma &lt;em&gt;modal&lt;/em&gt; ou um cabeçalho de uma &lt;em&gt;modal&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-4.png" alt="Imagem mostrando uma modal, em que na parte de cima, seu cabeçalho possui um título à esquerda e um botão de ação para fechar à direita. Abaixo há três botões: um para salvar, outro para limpar e à direita para cancelar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tanto o cabeçalho da modal como o rodapé têm elementos filhos que são exibidos em linha. Como você vê, o espaçamento entre eles é feito como abaixo.&lt;/p&gt;

&lt;p&gt;Para o cabeçalho da modal, fica assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.modal-header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;space-between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E para o rodapé, é um pouco diferente. A ação "Cancel" usa uma margem automática para se empurrar para a direita. Eu escrevi um &lt;a href="https://ishadeed.com/article/auto-css/" rel="noopener noreferrer"&gt;artigo detalhado&lt;/a&gt; sobre isso.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.cancel__action&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O nome da classe &lt;code&gt;.cancel__action&lt;/code&gt; pode não ser perfeito aqui, mas não quero entrar em convenções de nomenclatura de CSS para este artigo.&lt;/p&gt;

&lt;h4&gt;
  
  
  Elementos de formulário
&lt;/h4&gt;

&lt;p&gt;Uma combinação de um &lt;code&gt;input&lt;/code&gt; com um botão ao lado é um caso de uso perfeito para o Flexbox. Considere a figura abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-5.png" alt="Uma imagem com dois campos de formulário"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No primeiro formulário, o &lt;code&gt;input&lt;/code&gt; está ocupando todo o espaço restante, fazendo com que ele tenha uma largura dinâmica. O mesmo se aplica ao segundo formulário (Facebook Messenger), o campo de texto ocupa todo o espaço restante. Vamos olhar mais de perto.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-6.png" alt="Uma imagem mostrando dois campos de formulário"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.input&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Observe que, sem usar &lt;code&gt;flex: 1 1 auto&lt;/code&gt; no campo de texto, ele não se expandirá e preencherá o espaço restante.&lt;/p&gt;

&lt;h4&gt;
  
  
  Threads e comentários
&lt;/h4&gt;

&lt;p&gt;Outro caso de uso comum para o flexbox são as threads de comentários. Considere o seguinte exemplo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-7.png" alt="Uma imagem mostrando um exemplo de comentário em uma thread"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Temos a foto do usuário e o próprio comentário. O comentário está ocupando o espaço restante de seu elemento pai. Esse é um uso perfeito para o flexbox.&lt;/p&gt;

&lt;h4&gt;
  
  
  Componentes de card
&lt;/h4&gt;

&lt;p&gt;Um componente de &lt;em&gt;card&lt;/em&gt; tem muitas variações, mas o design mais comum é semelhante ao modelo abaixo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-8.png" alt="Imagem mostrando dois cards, um em formato de coluna e outro em linha"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;À esquerda, o ítens filhos do card são empilhados pois a direção definida na propriedade &lt;code&gt;flex-wrapper&lt;/code&gt; é &lt;code&gt;column&lt;/code&gt;. Enquanto que à direita é o oposto. A direção usada é &lt;code&gt;row&lt;/code&gt;, e tenha em mente que &lt;code&gt;row&lt;/code&gt; é o default para flexbox.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;800px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Outra variação comum para um cartão é ter um ícone com um &lt;em&gt;label&lt;/em&gt; de texto abaixo dele. Pode ser um botão, link ou apenas para decoração. Considere o seguinte modelo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-9.png" alt="Imagem mostrando três card, um ao lado do outro e em outro exemplo, um abaixo do outro"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note como o ícone e o &lt;em&gt;label&lt;/em&gt; do texto estão centralizados na horizontal e na vertical. Graças ao flexbox, isso é fácil de fazer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O estilo em linha será o padrão, basta remover a declaração &lt;code&gt;flex-direction: column&lt;/code&gt; e deixá-la no valor padrão (&lt;code&gt;row&lt;/code&gt;).&lt;/p&gt;

&lt;h4&gt;
  
  
  Tabs e Menus de botão
&lt;/h4&gt;

&lt;p&gt;Quando se trata de elementos que ocupam toda a largura da tela e têm itens que devem preencher todo o espaço disponível, o flexbox é a ferramenta perfeita aqui.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-10.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-10.png" alt="Imagem que mostra uma tab com 3 elementos dispostos em tamanho igual"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No exemplo acima, cada item deve preencher o espaço disponível e deve ter largura igual. Ao configurar a exibição do &lt;em&gt;wrapper&lt;/em&gt; para &lt;em&gt;flex&lt;/em&gt;, isso pode ser feito facilmente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.tabs__item&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;flex-grow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa técnica é usada no React Native para criar a barra de guias para aplicativos &lt;em&gt;mobile&lt;/em&gt;. Aqui está um exemplo de código que faz o mesmo que o descrito acima em React Native. O código é emprestado &lt;a href="https://reactnative.dev/docs/flexbox" rel="noopener noreferrer"&gt;deste local&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;View&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;FlexDirectionBasics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;View&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;View&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;View&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;View&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/View&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Lista de características
&lt;/h4&gt;

&lt;p&gt;O que eu mais gosto no flexbox é a capacidade de reverter a direção dos elementos. A direção padrão no flexbox é &lt;code&gt;row&lt;/code&gt;, mas podemos revertê-la como abaixo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.item&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row-reverse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na modelo abaixo, observe como o item par é revertido, isso é feito com a técnica acima. É muito útil.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-11.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-11.png" alt="Imagem mostrando 3 cards, em que o card do meio possui o ícone à direita e o texto à esquerda"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Centralizando uma seção de conteúdo
&lt;/h4&gt;

&lt;p&gt;Vamos considerar que temos uma seção &lt;code&gt;hero&lt;/code&gt;, e o conteúdo precisa estar centralizado horizontalmente e verticalmente. A centralização horizontal pode ser fácil pois poderia ser feito com o alinhamento de texto.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fflexbox-use-12.png" alt="Imagem mostrando uma hero section com os elementos centralizados horizontalmente"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.hero&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mas como podemos usar o flexbox para centralizar os elementos verticalmente? Aqui está o que precisamos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.hero&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* centralizar os elementos horizontalmente */&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* centralizar os elementos verticalmente */&lt;/span&gt;
  &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Combinando CSS grid e Flexbox
&lt;/h3&gt;

&lt;p&gt;Não apenas cada módulo de layout possui seu caso de uso, mas podemos usar ambos. Quando penso sobre combinar eles, o primeiro uso que eu vejo é uma lista de cards. Grid é usado para dispor os cards, e flexbox é usado para o componente card em si.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fgrid-and-flex.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fgrid-and-flex.png" alt="Imagem mostrando um grid de cards"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aqui estão os requisitos para o layout:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A altura dos &lt;em&gt;cards&lt;/em&gt; para cada linha deve ser igual&lt;/li&gt;
&lt;li&gt;O link "Read more" deve ser posicionado no final do &lt;em&gt;card&lt;/em&gt;, independentemente da sua altura.&lt;/li&gt;
&lt;li&gt;O grid deve usar a função &lt;code&gt;minmax()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"wrapper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;article&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"sunrise.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card__content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;&lt;span class="c"&gt;&amp;lt;!-- Title --&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="c"&gt;&amp;lt;!-- Desc --&amp;gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card_link"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Read more&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;500px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto-fill&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="py"&gt;grid-gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* [1] */&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* [2] */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.card__content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;flex-grow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* [3] */&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* [4] */&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.card__link&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* [5] */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deixe-me explicar o CSS acima:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Faz o card um wrapper flexbox.&lt;/li&gt;
&lt;li&gt;A direção usado é &lt;code&gt;column&lt;/code&gt;, o que significa que os elementos cards estão empilhados&lt;/li&gt;
&lt;li&gt;Deixa o conteúdo do card expandido e preencher o espaço restante.&lt;/li&gt;
&lt;li&gt;Faz o conteúdo do card um wrapper flexbox.&lt;/li&gt;
&lt;li&gt;Finalmente, usando &lt;code&gt;margin-top:auto&lt;/code&gt; para empurrar o item para baixo. Isto irá mantê-lo posicionado ao final do card independente da altura.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Como você viu, combinar CSS grid e flexbox não é difícil. Essas duas ferramentas podem nos dar várias maneiras de implementar layouts na web. Vamos usá-los corretamente e combiná-los &lt;strong&gt;somente&lt;/strong&gt; quando necessário, como acima.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fallback e suporte a navegadores antigos
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Usando CSS @supports
&lt;/h4&gt;

&lt;p&gt;Há alguns meses, recebi um &lt;em&gt;tweet&lt;/em&gt; dizendo que meu site estava quebrado no IE11. Depois de verificar, notei um comportamento muito estranho. Todo o conteúdo do site estava recolhido na área superior esquerda. Meu site não estava navegável!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fishadeed-ie11.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fishadeed-ie11.png" alt="Imagem mostrando todo o conteúdo do site colapsado à esquerda"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sim, este é o meu site - um site de um desenvolvedor front-end, no IE11. No começo, fiquei confuso, por que isso está acontecendo? Lembrei que o CSS grid é suportado no IE11, mas essa é a versão antiga lançada pela Microsoft. A solução é muito simples, que é usar o &lt;code&gt;@supports&lt;/code&gt; para usar somente a grade CSS em novos navegadores.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@supports&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;grid-area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deixe-me explicar isso. Eu usava &lt;code&gt;grid-area&lt;/code&gt; porque ela era suportada apenas na nova especificação do CSS grid, de março de 2017 até hoje. Uma vez que o IE não suporta a &lt;em&gt;query&lt;/em&gt; &lt;code&gt;@supports&lt;/code&gt;, toda a regra será ignorada. Como resultado, o novo CSS grid será usado apenas em navegadores que o suportam.&lt;/p&gt;

&lt;h4&gt;
  
  
  Usando o flexbox para suporte ao CSS grid
&lt;/h4&gt;

&lt;p&gt;Se o flexbox não é adequado para exibir uma grade de itens, isso não significa que não seja bom como fallback. Você pode usar o flexbox como substituto do CSS grid para navegadores não compatíveis. Eu trabalhei em uma &lt;a href="https://shadeed.github.io/grid-to-flex/" rel="noopener noreferrer"&gt;ferramenta&lt;/a&gt; que faz exatamente isso.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@mixin&lt;/span&gt; &lt;span class="nf"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-wrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;@supports&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;grid-area&lt;/span&gt;&lt;span class="nd"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="na"&gt;grid-gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@mixin&lt;/span&gt; &lt;span class="nf"&gt;gridAuto&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;320px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="m"&gt;99%&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nl"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nf"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="m"&gt;99%&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;768px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="m"&gt;99%&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nl"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nf"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="m"&gt;99%&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;@supports&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;grid-area&lt;/span&gt;&lt;span class="nd"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto-fit&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1fr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O código de fallback acima funciona da seguinte maneira:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Adiciona &lt;code&gt;display: flex&lt;/code&gt; e &lt;code&gt;flex-wrap: wrap&lt;/code&gt; ao elemento wrapper.&lt;/li&gt;
&lt;li&gt;Verifica se CSS grid é suportado, se sim, então &lt;code&gt;display: grid&lt;/code&gt; será usado.&lt;/li&gt;
&lt;li&gt;Usando o seletor &lt;code&gt;&amp;gt; *&lt;/code&gt;, podemos selecionar os elementos filhos diretos do wrapper. Ao selecioná-los, podemos adicionar uma largura ou tamanho específico a cada um.&lt;/li&gt;
&lt;li&gt;Obviamente, a margem entre cada uma é necessária e será substituída por &lt;code&gt;grid-gap&lt;/code&gt;, caso CSS grid seja suportado.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Aqui está um exemplo de como usar este mixin do Sass.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;gridAuto&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://codepen.io/shadeed/pen/XWrLmYe" rel="noopener noreferrer"&gt;Demostracão&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Quando as coisas dão errado para o Grid e o Flexbox
&lt;/h3&gt;

&lt;p&gt;Enquanto fazia uma revisão de código para o meu irmão, notei alguns usos incorretos para o CSS grid ou o flexbox e achei que seria útil se eu destacasse alguns deles.&lt;/p&gt;

&lt;h4&gt;
  
  
  Usar CSS grid para um cabeçalho de site
&lt;/h4&gt;

&lt;p&gt;Uma das motivações deste artigo foi esse erro. Notei que meu irmão está usando CSS Grid para implementar um cabeçalho de site.&lt;/p&gt;

&lt;p&gt;Ele mencionou coisas como "era complexo, CSS Grid é difícil... etc". Como resultado do uso de um método de layout incorreto, ele teve uma ideia de que o CSS grid é complexo. Não é, e toda a sua confusão veio do fato de usá-lo para algo que não é adequado.&lt;/p&gt;

&lt;p&gt;Considere o seguinte exemplo que eu notei.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fincorrect-use-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fincorrect-use-1.png" alt="Imagem mostrando o uso incorreto de css grid num cabecalho"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.site-header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.site-nav&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O CSS grid foi usada duas vezes, a primeira vez foi para todo o cabeçalho e a segunda para a navegação. Ele usou &lt;code&gt;grid-column&lt;/code&gt; para ajustar o espaçamento entre os elementos e outras coisas estranhas que não me lembro, mas você entendeu!&lt;/p&gt;

&lt;h4&gt;
  
  
  Usando CSS Grid para tabs
&lt;/h4&gt;

&lt;p&gt;Outro uso incorreto do CSS Grid é aplicá-lo em um componente de tabs. Considere o seguinte modelo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fincorrect-use-2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fincorrect-use-2.png" alt="Imagem mostrando o uso incorreto de css grid em tabs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O código CSS incorreto se parece com o seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.tabs-wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pelo código acima, posso ver que o desenvolvedor assumiu que a contagem de tabs é de apenas três. Como resultado, ele usou &lt;code&gt;1fr 1fr 1fr&lt;/code&gt; para organizar as colunas. Isso pode ser quebrado facilmente se a contagem de colunas for alterada.&lt;/p&gt;

&lt;h4&gt;
  
  
  Uso excessivo de Flexbox ou Grid
&lt;/h4&gt;

&lt;p&gt;Lembre-se de que o antigo método de layout pode ser perfeito para o trabalho. O uso excessivo de flexbox ou grid pode aumentar a complexidade do seu CSS com o tempo. Não estou dizendo que eles são complexos, mas usá-los &lt;strong&gt;corretamente&lt;/strong&gt; e no contexto certo, conforme explicado nos exemplos deste artigo, é muito melhor.&lt;/p&gt;

&lt;p&gt;Por exemplo, você tem a seguinte seção &lt;code&gt;hero&lt;/code&gt; com uma solicitação para centralizar horizontalmente todo o conteúdo dela.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fhero-centered.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fishadeed.com%2Fassets%2Fgrid-flex%2Fhero-centered.png" alt="Imagem mostrando um form de solitacão com um botão de Leia Mais"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isso pode ser feito simplesmente usando &lt;code&gt;text-align: center&lt;/code&gt;. Porque usar flexbox quando há uma solução mais fácil?&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Ufa, isso foi muito sobre as diferenças entre o uso de grid CSS e flexbox. Este tópico estava em minha mente por muito tempo, e eu fico feliz que eu tive a chance de escrever sobre ele. Por favor, não hesite de dar um &lt;em&gt;feedback&lt;/em&gt; tanto por email ou twitter &lt;a href="https://twitter.com/shadeed9" rel="noopener noreferrer"&gt;@shadeed9&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Obrigado pela leitura.&lt;/p&gt;




&lt;p&gt;E é isso, espero que tenha gostado. Não deixe de seguir &lt;a href="https://twitter.com/shadeed9" rel="noopener noreferrer"&gt;Ahmad Shadeed&lt;/a&gt; no Twitter. Ele sempre vem com textos bem completos sobre CSS e Design. E se você gostou deste post, não esqueça de curtir ele e compartilhá-lo em suas redes sociais.&lt;/p&gt;

&lt;p&gt;Até o próximo post!&lt;/p&gt;

</description>
      <category>grid</category>
      <category>flexbox</category>
      <category>css</category>
      <category>componentização</category>
    </item>
    <item>
      <title>Headless CMS, o que são? onde vivem? o que comem?</title>
      <dc:creator>Emanuel Gonçalves</dc:creator>
      <pubDate>Fri, 05 Jun 2020 02:48:21 +0000</pubDate>
      <link>https://dev.to/codecasts/headless-cms-o-que-sao-onde-vivem-o-que-comem-3nm</link>
      <guid>https://dev.to/codecasts/headless-cms-o-que-sao-onde-vivem-o-que-comem-3nm</guid>
      <description>&lt;p&gt;Em Outubro de 2019 eu entrei para uma empresa de um produto bem interessante e de um mercado que não conhecia muito: &lt;a href="https://www.storyblok.com/" rel="noopener noreferrer"&gt;a Storyblok&lt;/a&gt;. Além de trabalhar com linguagens que eu já gostava muito e com um time fera e internacional, estou tendo a oportunidade de lidar com uma tecnologia bem interessante e moderna: &lt;strong&gt;Headless CMS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O motivo para a escrita deste texto é trazer para você conhecimentos que eu não tive no passado e despertar o interesse por novas soluções no ecossistema de CMS. Então, esquece de colocar no Google Tradutor o termo "Headless CMS", porquê a resposta não é animadora (spoiler: é "CMS Sem cabeça"). Venha conferir o que são Headless CMS, onde vivem, e o que comem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evolução do conceito de CMS na internet
&lt;/h2&gt;

&lt;p&gt;Antes, vamos investigar rapidamente a evolução que a internet teve e o papel dos Gerenciadores de Conteúdo nessa evolução.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Web 1.0
&lt;/h3&gt;

&lt;p&gt;Características:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Estática&lt;/strong&gt;, os navegadores apenas entendiam HTML e a interação era nula;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Celeiro de informações&lt;/strong&gt;: a Web 1.0, mesmo tendo as características acima, era extremamente revolucionária, pois agora era possível armazenar conhecimento e compartilhá-lo como jamais visto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Armazenamento em arquivos&lt;/strong&gt;: a web era feita de arquivos HTML que eram publicados através de um FTP. Precisa mudar o conteúdo? Edite o arquivo e suba novamente.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Com o advento dos anos 2000 e o surgimento de ferramentas como PHP e ASP, a Web passou por uma grande mudança, vindo agora a Web 2.0.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Web 2.0
&lt;/h3&gt;

&lt;p&gt;Sem dúvida, o que propiciou o surgimento dessa revolução foram ao menos três fatores:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Possibilidade de &lt;strong&gt;criação de conteúdo dinâmico&lt;/strong&gt;. Era possível deixar comentários nos posts, por exemplo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;O conteúdo poderia ser armazenado em bases de dados&lt;/strong&gt;, diferentemente do formato anterior, em que o conteúdo era armazenado em arquivos, como por exemplo, o próprio HTML.&lt;/li&gt;
&lt;li&gt;Surgimento de linguagens que permitiam uma dinamização na criação de conteúdo e acesso à base de dados, como &lt;a href="https://www.youtube.com/watch?v=AqDj3OSV0mM" rel="noopener noreferrer"&gt;PHP&lt;/a&gt; e &lt;a href="https://pt.wikipedia.org/wiki/ASP" rel="noopener noreferrer"&gt;ASP&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Portanto, a principal característica da Web era ser dinâmica, sendo assim  possível adicionar conteúdos, editá-los e o consumidor final (o usuário) poder interagir com este conteúdo, por exemplo, criando comentários em posts.&lt;/p&gt;

&lt;p&gt;É aqui que os grandes players do mercado de CMS surgem (mais a frente iremos investigar o que são os CMSs) como o &lt;a href="https://br.wordpress.com/" rel="noopener noreferrer"&gt;Wordpress&lt;/a&gt; e o &lt;a href="https://www.drupal.org/" rel="noopener noreferrer"&gt;Drupal&lt;/a&gt; e os &lt;em&gt;Site Builders&lt;/em&gt;, que são ferramentas que praticamente constroem o site para você. Tudo isso surge para facilitar a vida dos produtores de conteúdo, pois agora não era mais necessário ter conhecimentos específicos de programação web para ter um site no ar.&lt;/p&gt;

&lt;p&gt;Porém, mais um elemento é adicionado a sociedade: o &lt;strong&gt;&lt;em&gt;smartphone&lt;/em&gt;&lt;/strong&gt;. E com ele, a possibilidade de acessar as mesmas páginas web que antes o usuário acessava no computador por esse novo dispositivo.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Web 3.0
&lt;/h3&gt;

&lt;p&gt;Com o advento dos &lt;em&gt;smartphones&lt;/em&gt; e algumas evoluções no acesso aos dados, como por exemplo, a possibilidade de automação da leitura de uma página web (criação dos &lt;em&gt;crawlers&lt;/em&gt; web), a web precisou se reinventar. Surgindo assim a &lt;strong&gt;Web semântica&lt;/strong&gt;. É nesta era que surge o &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/HTML/HTML5" rel="noopener noreferrer"&gt;HTML5&lt;/a&gt;, que possibilita a estruturação do conteúdo web para que não humanos entendam.&lt;/p&gt;

&lt;p&gt;Tal evolução trouxe um grande desafio aos CMSs: praticamente qualquer dispositivo consegue acessar a internet. Temos não apenas computadores, &lt;em&gt;smartphones&lt;/em&gt; e &lt;em&gt;tablets&lt;/em&gt; que acessam a internet, mas geladeiras, arduínos, &lt;em&gt;smartwatches&lt;/em&gt; entre outros. Na presente era da internet, que alguns comumente chamam de &lt;strong&gt;Web 4.0&lt;/strong&gt;, o desafio é entregar o conteúdo para qualquer dispositivo da melhor maneira.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mas, e os CMS?
&lt;/h2&gt;

&lt;p&gt;Um CMS (sigla para Content Management System - Sistema de Gerenciamento de conteúdo), é um software responsável por &lt;strong&gt;gerenciar o conteúdo&lt;/strong&gt;, ou seja, permitir a criação, edição e organização de um determinado conteúdo.&lt;/p&gt;

&lt;p&gt;Ele precisa possuir, ao menos, alguns destes elementos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Um &lt;strong&gt;Dashboard&lt;/strong&gt; para o produtor de conteúdo: é aqui que temos a liberdade para gerenciar o conteúdo, criar páginas, editá-las, escolher os temas que queremos entre outros.&lt;/li&gt;
&lt;li&gt;Ferramentas para publicação do conteúdo. Uma das etapas mais importantes é a publicação do conteúdo, ou seja, disponibilizá-lo na rede. Um CMS precisa de uma ferramenta para publicar o conteúdo e ela precisa ser simples para o usuário, já que o objetivo é que pessoas sem conhecimento técnico possam fazer uso de um CMS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Com a possibilidade de variados dispositivos acessarem a internet, o que chamamos de &lt;a href="https://rockcontent.com/blog/internet-das-coisas/" rel="noopener noreferrer"&gt;Internet das Coisas&lt;/a&gt;, surge um desafio aos CMSs tradicionais, vejamos.&lt;/p&gt;

&lt;h3&gt;
  
  
  O problema dos CMSs tradicionais
&lt;/h3&gt;

&lt;p&gt;Proponho a seguinte analogia para entendermos qual o principal problema de um CMS Tradicional e o surgimento dos Headless CMSs:&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1264622637507997696-77" src="https://platform.twitter.com/embed/Tweet.html?id=1264622637507997696"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1264622637507997696-77');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1264622637507997696&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Traduzindo...&lt;br&gt;
Um CMS Tradicional é como o livro que você compra em uma livraria. Quer acessar o conteúdo? Você pega o livro e lê ele, e esta é a única forma. Um Headless CMS é como comprar um eBook. Você lê ele no Amazon Kindle, ou você usa o aplicativo do Kindle no PC, Mac, smartphone ou Tablet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;O principal problema de um CMS Tradicional é que o conteúdo está "amarrado" à implementação do CMS&lt;/strong&gt;. Em termos técnicos, Front-End (o resultado final para quem consome o conteúdo) está acoplado ao Back-End (implementação do CMS). Como na analogia acima, o conteúdo (texto escrito pelo autor do livro) pode estar amarrado à uma interface física (livro) ou desacoplado da mesma (ebook), possibilitando seu consumo em diferentes interfaces.&lt;/p&gt;

&lt;p&gt;Veja a seguinte imagem que mostra a mesma ideia da analogia anterior:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.contentstack.io%2Fv3%2Fassets%2Fblt1264fa9b448be721%2Fblt7fb0e48ec6d3ad63%2F5d0a4e58d8ff351753cbdadb%2Fdownload" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.contentstack.io%2Fv3%2Fassets%2Fblt1264fa9b448be721%2Fblt7fb0e48ec6d3ad63%2F5d0a4e58d8ff351753cbdadb%2Fdownload" alt="Infográfico mostrando a diferença entre um Traditional e Headless CMS"&gt;&lt;/a&gt;&lt;/p&gt;

Fonte: https://www.contentstack.com/blog/all-about-headless/headless-cms-vs-building-custom-cms




&lt;p&gt;Portanto, os &lt;strong&gt;Headless CMSs surgem para suprir essa necessidade de gerenciar o conteúdo da melhor forma para diferentes dispositivos&lt;/strong&gt;. Mas como se dá isso?&lt;/p&gt;

&lt;h2&gt;
  
  
  Conhecendo mais a fundo um headless CMS
&lt;/h2&gt;

&lt;p&gt;Já vimos um pouco da evolução da internet e como os CMSs estavam e estão nela. Vimos como funciona um CMS tradicional e como ele, no novo contexto da internet, possui algumas limitações e também vimos como os Headless CMSs as suprem. Mas, como funciona um Headless CMS?&lt;/p&gt;

&lt;p&gt;Um Headless CMSs irá prover uma interface tal como um CMS comum teria. Porém, a diferença primordial dele é que, no final, você não terá o Front End pronto. Você precisará desenvolver um que consuma o conteúdo que está no CMS. Assim, um Headless CMS não se preocupa em como o seu conteúdo ficará no final, &lt;strong&gt;ele se preocupa apenas em como o conteúdo estará estruturado&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quais as vantagens?
&lt;/h3&gt;

&lt;p&gt;Como a preocupação é apenas com a estrutura do conteúdo e o Front End é desacoplado da solução, temos como consequência:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;flexibilidade&lt;/strong&gt; para escolher a tecnologia que você deseja usar e julga ser a melhor para o projeto.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Facilidade de configuração e implantação do código&lt;/strong&gt;, pois você não precisará de um Back End, apenas do Front. Então qualquer &lt;em&gt;static hoisting&lt;/em&gt; irá ser suficiente.&lt;/li&gt;
&lt;li&gt;A flexibilidade para transpor o mesmo conteúdo para ambientes/dispositivos diferentes, que outrora era a maior dificuldade que CMS tradicional enfrentava.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A melhor parte: &lt;strong&gt;Headless CMS não diz respeito apenas a web sites&lt;/strong&gt;. Você pode usar um Headless CMS para a criação de aplicativos &lt;em&gt;mobile&lt;/em&gt; e &lt;em&gt;desktop&lt;/em&gt;, entre outros usos.&lt;/p&gt;

&lt;h3&gt;
  
  
  E as desvantagens?
&lt;/h3&gt;

&lt;p&gt;Creio que há ao menos duas desvantagens que você pode encontrar ao usar um Headless CMS, mas que são contornáveis:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Como o seu site não está acoplado ao CMS, não será possível fazer uso de ferramentas de Analytics diretamente pela plataforma/ferramenta que gerencia o conteúdo, como por exemplo, saber quantas pessoas acessaram o site, quais páginas visitaram entre outros dados. Porém, você pode usar o seu &lt;em&gt;static hosting&lt;/em&gt; para ter essas informações ou usar o &lt;a href="https://analytics.google.com/analytics/web/" rel="noopener noreferrer"&gt;Google Analytics&lt;/a&gt; em conjunto com o &lt;a href="https://search.google.com/search-console?hl=pt-BR" rel="noopener noreferrer"&gt;Google Search&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Você poderá não ter acesso ao resultado final do conteúdo estruturado ao mesmo tempo que gerencia ele. Como Front e Back não estão juntos, você pode achar que criar a estrutura do conteúdo seja algo muito abstrato. Porém, &lt;strong&gt;existe uma solução de Headless CMS que o &lt;em&gt;core feature&lt;/em&gt; é a solução para isso: &lt;a href="https://www.storyblok.com/" rel="noopener noreferrer"&gt;a Storyblok&lt;/a&gt;&lt;/strong&gt; 😜😏.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Quais os tipos
&lt;/h3&gt;

&lt;p&gt;Podemos separar as soluções de Headless CMS em dois tipos, baseados em como ocorre a entrega e o consumo dos dados:&lt;/p&gt;

&lt;h4&gt;
  
  
  API driven
&lt;/h4&gt;

&lt;p&gt;Esta é a solução mais comum. O CMS disponibiliza uma &lt;a href="https://www.youtube.com/watch?v=vGuqKIRWosk" rel="noopener noreferrer"&gt;API&lt;/a&gt; para o consumo dos dados, e o Front End a usa. Alguns exemplos de soluções no mercado são: &lt;a href="https://www.storyblok.com/" rel="noopener noreferrer"&gt;Storyblok&lt;/a&gt;, &lt;a href="https://contentful.com/" rel="noopener noreferrer"&gt;Contentful&lt;/a&gt; e &lt;a href="https://prismic.io/" rel="noopener noreferrer"&gt;Prismic&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alguns pontos positivos desta solução são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Melhor solução para múltiplos front-ends&lt;/li&gt;
&lt;li&gt;Mais fácil de lidar quando há muito conteúdo&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mas alguns pontos negativos são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Geralmente vem com limite no consumo de dados&lt;/li&gt;
&lt;li&gt;Como não é integrado ao Git, pode ser complicado reverter mudanças&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Git driven
&lt;/h4&gt;

&lt;p&gt;Nesta solução, cada alteração no conteúdo irá gerar um novo &lt;em&gt;commit&lt;/em&gt; num repositório git, e assim, uma nova versão do site será gerada. Alguns exemplos são: &lt;a href="https://www.netlifycms.org/" rel="noopener noreferrer"&gt;NetlifyCMS&lt;/a&gt; e &lt;a href="https://forestry.io/" rel="noopener noreferrer"&gt;Forestry&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Alguns pontos positivos desta solução são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configuração simples&lt;/li&gt;
&lt;li&gt;Fácil voltar uma versão, seja específica ou não&lt;/li&gt;
&lt;li&gt;Integração com o git permite uma curva de aprendizado melhor (claro, se já souber e dominar o git)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Porém, alguns pontos negativos são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A forma como o conteúdo irá ser estruturado é limitado&lt;/li&gt;
&lt;li&gt;Se o site tiver bastante conteúdo, pode ser um problema&lt;/li&gt;
&lt;li&gt;Se há vários sites/aplicativos acessando o mesmo conteúdo, pode não ser a melhor escolha&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Recomendo fortemente a leitura do &lt;a href="https://bejamas.io/blog/git-based-cms-vs-api-first-cms/" rel="noopener noreferrer"&gt;artigo do Bejamas (em inglês)&lt;/a&gt; a respeito desse assunto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Considerações finais
&lt;/h2&gt;

&lt;p&gt;Headless CMS é uma solução bem interessante para o seu próximo blog, seu website de campanha de marketing ou até mesmo sua página pessoal na web. Existem inúmeras soluções no mercado. Recomendo o &lt;a href="https://bejamas.io/blog/headless-cms/" rel="noopener noreferrer"&gt;post do time do Bejamas sobre essas diferentes soluções&lt;/a&gt;. É um excelente comparativo, mostrando prós e contras de cada solução.&lt;/p&gt;

&lt;p&gt;Vejo você no próximo post!&lt;/p&gt;

&lt;h2&gt;
  
  
  Leituras adicionais
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.contentstack.com/blog/all-about-headless/content-management-systems-history-and-headless-cms" rel="noopener noreferrer"&gt;Post da ContentStack sobre a história dos CMSs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bejamas.io/blog/content-management-systems/" rel="noopener noreferrer"&gt;Post do Bejamas com um overview de Headless CMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.storyblok.com/tp/headless-cms-explained" rel="noopener noreferrer"&gt;Post da Storyblok explicando o que é um Headless CMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hackernoon.com/headless-cms-vs-traditional-cms-521ad6fda420" rel="noopener noreferrer"&gt;Headless CMS vs CMS Tradicionais do Hackernoon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://agilitycms.com/resources/guide/top-10-reasons-why-you-should-choose-a-headless-cms-over-a-traditional-cms" rel="noopener noreferrer"&gt;Post da Agility sobre dez motivos para se usar um Headless CMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bejamas.io/blog/git-based-cms-vs-api-first-cms/" rel="noopener noreferrer"&gt;Post do Bejamas sobre os tipos de Headless CMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bejamas.io/blog/headless-cms/" rel="noopener noreferrer"&gt;Post do Bejamas com uma lista com inúmeras soluções no mercado de Headless CMS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Agradecimentos ao &lt;a href="https://dev.to/vinicius73"&gt;Vinicius Reis&lt;/a&gt; pela revisão e pela imagem 😎&lt;/p&gt;

</description>
      <category>headless</category>
      <category>cms</category>
      <category>storyblok</category>
    </item>
    <item>
      <title>Suspense - uma nova feature no Vue3</title>
      <dc:creator>Emanuel Gonçalves</dc:creator>
      <pubDate>Mon, 03 Feb 2020 19:48:23 +0000</pubDate>
      <link>https://dev.to/codecasts/suspense-uma-nova-feature-no-vue3-172g</link>
      <guid>https://dev.to/codecasts/suspense-uma-nova-feature-no-vue3-172g</guid>
      <description>&lt;p&gt;Fala galera, esta é mais uma tradução livre de um artigo do pessoal do &lt;a href="https://vueschool.io/articles/"&gt;Vueschool&lt;/a&gt;, dessa vez sobre uma outra feature do Vue 3, que é o componente &lt;code&gt;Suspense&lt;/code&gt;. Não deixe de conferir!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vueschool.io/articles/vuejs-tutorials/suspense-new-feature-in-vue-3/"&gt;Link do post original&lt;/a&gt; escrito pelo &lt;a href="https://twitter.com/filrakowski"&gt;Filip Rakowski&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Recentemente eu escrevi um artigo sobre &lt;a href="https://vueschool.io/articles/vuejs-tutorials/exciting-new-features-in-vue-3/"&gt;as novas features disponíveis no Vue 3&lt;/a&gt; (&lt;a href="https://dev.to/codecasts/conheca-as-novas-funcionalidades-do-vue-3-o2g"&gt;texto também traduzido&lt;/a&gt;) onde eu brevemente introduzi quais features podemos esperar na próxima major release do Vue.js.&lt;/p&gt;

&lt;p&gt;No artigo de hoje, eu quero falar um pouco mais sobre uma das mais interessantes - Suspense.&lt;/p&gt;

&lt;p&gt;Este artigo é baseado no repositório vue-next. Não há garantia de que os recursos mencionados neste artigo cheguem ao Vue 3 exatamente da forma descrita (mas é provável que aconteça).&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é o Suspense?
&lt;/h2&gt;

&lt;p&gt;Suspense é um componente especial que renderiza um conteúdo de &lt;em&gt;fallback&lt;/em&gt; em vez do seu componente até que uma condição seja atendida. Essa condição geralmente é uma operação assíncrona acontecendo na função &lt;code&gt;setup&lt;/code&gt; de seus componentes. Esta é uma técnica &lt;a href="https://pl.reactjs.org/docs/concurrent-mode-reference.html#suspense"&gt;bem conhecida do ecossistema React&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Se isso parece estranho para você, não se assuste. Eu vou me aprofundar nisso brevemente.&lt;/p&gt;

&lt;p&gt;Com a &lt;em&gt;Composition API&lt;/em&gt;, Vue 3 irá introduzir um método &lt;code&gt;setup&lt;/code&gt;, que permite conectar diferentes propriedades de componentes com funções como &lt;code&gt;computed()&lt;/code&gt; ou &lt;code&gt;onMounted()&lt;/code&gt;. Propriedades retornadas pelo método &lt;code&gt;setup&lt;/code&gt; estarão disponíveis no template Vue da mesma forma que &lt;code&gt;data&lt;/code&gt;, &lt;code&gt;methods&lt;/code&gt;, e &lt;code&gt;computeds&lt;/code&gt; da &lt;em&gt;Options API&lt;/em&gt; do Vue 2 são disponíveis agora.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt; 
    Clicked &lt;span class="nt"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;{{ count }}&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt; times. 
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"increment"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Increment&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;setup&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;increment&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;    

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;increment&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Às vezes você quer realizar uma operação assíncrona no método &lt;code&gt;setup&lt;/code&gt; como uma requisição de dados para uma API externa (similarmente ao se faz atualmente no método &lt;code&gt;created&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;setup&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetchUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;    
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste caso, você provavelmente não quer visualizar seu componente enquanto se está buscando os dados do usuário. Você provavelmente quer visualizar algum indicador de &lt;em&gt;loading&lt;/em&gt; enquanto se está sendo buscado os dados. É exatamente para isso que o &lt;code&gt;Suspense&lt;/code&gt; foi feito!&lt;/p&gt;

&lt;p&gt;Se nós encapsulamos o componente abaixo em um &lt;code&gt;Suspense&lt;/code&gt;, ele irá mostrar uma conteúdo de &lt;em&gt;fallback&lt;/em&gt; enquanto a operação assíncrona do seu componente é resolvida.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Suspense&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;#default&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;UserProfile&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;#fallback&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Loading...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Suspense&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Muito elegante, não? Também podemos suspender o carregamento para vários componentes assíncronos.&lt;/p&gt;

&lt;p&gt;Se tivermos outro componente que busca imagens engraçadas de gatos e o coloca junto com o componente &lt;code&gt;UserProfile&lt;/code&gt;, o conteúdo de &lt;em&gt;fallback&lt;/em&gt; será mostrado até que ambos os componentes resolvam suas operações assíncronas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Suspense&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;#default&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;UserProfile&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;FunnyCats&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt; 
  &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;#fallback&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Loading...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Suspense&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Manipulação de erros
&lt;/h2&gt;

&lt;p&gt;Até agora, cobrimos o que acontece quando as operações assíncronas são resolvidas com êxito, mas o que acontece se elas falharem e forem rejeitadas?&lt;/p&gt;

&lt;p&gt;Felizmente, podemos usar o novo &lt;em&gt;hook&lt;/em&gt; de ciclo de vida &lt;code&gt;ErrorCaptured&lt;/code&gt; para capturar erros como esse e exibir uma mensagem de erro adequada. Veja o exemplo abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"error"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
   {{ error }}
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;Suspense&lt;/span&gt; &lt;span class="na"&gt;v-else&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;#default&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;UserProfile&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;#fallback&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Loading...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/Suspense&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;onErrorCaptured&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;setup&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;onErrorCaptured&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;})}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima, nós visualizamos um conteúdo de &lt;em&gt;fallback&lt;/em&gt; até que a operação assíncrona em &lt;code&gt;UserProfile&lt;/code&gt; seja resolvida. Se algo acontece de errado e ela é rejeitada, nós usamos o &lt;em&gt;hook&lt;/em&gt; &lt;code&gt;onErrorCaptured&lt;/code&gt; do Vue para capturar o erro e passá-lo para uma propriedade &lt;code&gt;error&lt;/code&gt; e visualizá-la ao invés do nosso conteúdo de &lt;em&gt;fallback&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resumo
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Suspense&lt;/code&gt; é um componente muito acessível que disponibiliza uma maneira fácil e elegante de visualizar um conteúdo de &lt;em&gt;fallback&lt;/em&gt; enquanto operações assíncronas são executadas. Com o &lt;em&gt;hook&lt;/em&gt; de ciclo de vida &lt;code&gt;ErrorCaptured&lt;/code&gt; você também pode graciosamente manipular os erros que acontecem no seu componente "suspendido".&lt;/p&gt;




&lt;p&gt;Bom, mais uma tradução finalizada. Espero que tenha gostado. Não deixe de compartilhar este post para que mais pessoas sejam alcançadas por este conhecimento.&lt;/p&gt;

&lt;p&gt;Até a próxima!&lt;/p&gt;

</description>
      <category>suspense</category>
      <category>javascript</category>
      <category>vue</category>
    </item>
    <item>
      <title>Portal - uma nova feature no Vue 3</title>
      <dc:creator>Emanuel Gonçalves</dc:creator>
      <pubDate>Fri, 24 Jan 2020 11:18:05 +0000</pubDate>
      <link>https://dev.to/codecasts/portal-uma-nova-feature-no-vue-3-2124</link>
      <guid>https://dev.to/codecasts/portal-uma-nova-feature-no-vue-3-2124</guid>
      <description>&lt;p&gt;Fala galera, esta é mais uma tradução livre de um artigo do pessoal do &lt;a href="https://vueschool.io/articles/"&gt;Vueschool&lt;/a&gt;, dessa vez sobre uma outra feature do Vue 3, que são os Portals ou Portais. Não deixe de conferir!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vueschool.io/articles/vuejs-tutorials/portal-a-new-feature-in-vue-3/"&gt;Link do post original&lt;/a&gt; escrito pelo &lt;a href="https://twitter.com/filrakowski"&gt;Filip Rakowski&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Recentemente eu escrevi um artigo sobre &lt;a href="https://vueschool.io/articles/vuejs-tutorials/exciting-new-features-in-vue-3/"&gt;as novas features disponíveis no Vue 3&lt;/a&gt; (&lt;a href="https://dev.to/codecasts/conheca-as-novas-funcionalidades-do-vue-3-o2g"&gt;texto também traduzido&lt;/a&gt;) onde eu brevemente introduzi quais &lt;em&gt;features&lt;/em&gt; podemos esperar na próxima &lt;em&gt;major release&lt;/em&gt; do Vue.js.&lt;/p&gt;

&lt;p&gt;No artigo de hoje, eu quero falar um pouco mais sobre uma das mais úteis - Portais.&lt;/p&gt;

&lt;p&gt;Este artigo é baseado no repositório vue-next. Não há garantia de que os recursos mencionados neste artigo cheguem ao Vue 3 exatamente da forma descrita (mas é provável que aconteça).&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é um portal?
&lt;/h2&gt;

&lt;p&gt;Portal é um conceito bem conhecido do React que também foi adotado no Vue 2 através de plugins de terceiros como o &lt;a href="https://github.com/LinusBorg/portal-vue"&gt;portal-vue&lt;/a&gt;. Como o nome sugere, ele é responsável por "teletransportar" algo de um lugar para outro... E é exatamente o que ele faz!&lt;/p&gt;

&lt;p&gt;Com um portal, você pode renderizar um componente em um local diferente na árvore DOM, mesmo que este local não esteja no escopo do seu app. Portais são muito convenientes quando trabalhamos com &lt;em&gt;modals&lt;/em&gt;, &lt;em&gt;notifications&lt;/em&gt;, &lt;em&gt;popups&lt;/em&gt; e outros elementos que são sensíveis ao local em que eles estão na árvore DOM.&lt;/p&gt;

&lt;p&gt;Deixe-me te mostrar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- UserCard.vue --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"user-card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;b&amp;gt;&lt;/span&gt; {{ user.name }} &lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt;  
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"isPopUpOpen = true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Remove user&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-show=&lt;/span&gt;&lt;span class="s"&gt;"isPopUpOpen"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Are you sure?&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"removeUser"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Yes&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"isPopUpOpen = false"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;No&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No código acima nos temos um componente &lt;code&gt;UserCard&lt;/code&gt; que nos permite remover um determinado usuário de um banco de dados. Depois de clicar no botão, nós iremos ver um &lt;em&gt;popup&lt;/em&gt; de confirmação no qual podemos confirmar a ação e remover o usuário usando o método &lt;code&gt;removeUser&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Manter componentes relacionados (o &lt;em&gt;popup&lt;/em&gt; de confirmação por exemplo) no mesmo local é uma boa prática em termos de manutenção de código. Mas, quando se trata de elementos de UI que podem aparecer acima de outros, podemos ter alguns problemas.&lt;/p&gt;

&lt;p&gt;O primeiro problema que podemos encontrar é o fato de que a classe &lt;code&gt;user-card&lt;/code&gt;, assim como qualquer outra classe mais alta na hierarquia do DOM, pode afetar a aparência do nosso &lt;em&gt;popup&lt;/em&gt;. Por exemplo, se qualquer container definir &lt;code&gt;visibility: 0.5&lt;/code&gt;, a visibilidade de nosso &lt;em&gt;popup&lt;/em&gt; também será afetada.&lt;/p&gt;

&lt;p&gt;Garantir que nosso &lt;em&gt;popup&lt;/em&gt; irá aparecer no topo de outros elementos é um outro desafio. Você pode pensar no elementos DOM como camadas. Nós colocamos estas camadas acima de outras para construir um layout. Normalmente, quando nós queremos cobrir uma dessas camadas com outras, nós fazemos isso intencionalmente colocando outros elementos &lt;strong&gt;dentro&lt;/strong&gt; dessa camadas ou &lt;strong&gt;depois&lt;/strong&gt; dela.&lt;/p&gt;

&lt;p&gt;Uma das formas de resolver este problema é usando a propriedade &lt;code&gt;z-index&lt;/code&gt; do CSS para mudar a ordem natural de aparência de um elemento. Contudo, este método não é muito elegante e normalmente nos traz outros desafios para enfrentar, como quando temos outros elementos posicionados com &lt;code&gt;z-index&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;É por isso que geralmente colocamos elementos de UI que devem aparecer em cima dos outros antes da tag de fechamento &lt;code&gt;&amp;lt;/body&amp;gt;&lt;/code&gt;. Dessa forma, não precisamos fazer hacks para garantir que nosso &lt;em&gt;popup&lt;/em&gt; seja exibido exatamente onde e como queremos. Também garante que outros elementos não o cubram.&lt;/p&gt;

&lt;p&gt;Portanto, parece que temos duas boas práticas que entram em conflito:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O primeiro diz para mantermos os componentes relacionados juntos, o que implica manter o componente &lt;em&gt;popup&lt;/em&gt; dentro do componente &lt;code&gt;UserCard&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;O segundo nos diz para colocar o componente &lt;em&gt;popup&lt;/em&gt; imediatamente antes do fechamento da tag &lt;code&gt;body&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para atender a ambos os requisitos, precisamos garantir que, mesmo que o código do nosso &lt;em&gt;popup&lt;/em&gt; esteja localizado no componente &lt;code&gt;UserCard&lt;/code&gt;, ele seja renderizado em outro lugar - idealmente antes do fechamento da tag &lt;code&gt;body&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Felizmente, é exatamente para isso que os portais foram criados!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Portais no Vue 3
&lt;/h2&gt;

&lt;p&gt;Entre muitos outros recursos, o Vue 3 virá com suporte nativo para portais na através do componente &lt;code&gt;Portal&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A boa notícia é que o componente &lt;code&gt;Portal&lt;/code&gt; é muito simples! Ele possui apenas uma propriedade, &lt;code&gt;target&lt;/code&gt;, e um slot padrão. O conteúdo do slot será renderizado no elemento DOM, selecionado pelo seletor de consulta passado na propriedade &lt;code&gt;target&lt;/code&gt; do componente &lt;code&gt;Portal&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- In some nested Vue component --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;NestedComponent&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;Portal&lt;/span&gt; &lt;span class="na"&gt;target=&lt;/span&gt;&lt;span class="s"&gt;"#popup-target"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PopUp&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/Portal&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/NestedComponent&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- before closing body tag --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"popup-target"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima, o componente &lt;code&gt;PopUp&lt;/code&gt; irá ser renderizado numa div com um id &lt;code&gt;popup-target&lt;/code&gt;, mesmo que esteja posicionado dentro de um componente &lt;code&gt;NestedComponent&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Sabendo disso, podemos reescrever nosso componente &lt;code&gt;UserCard&lt;/code&gt; neste formato:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- UserCard.vue --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"user-card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;b&amp;gt;&lt;/span&gt; {{ user.name }} &lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt;  
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"isPopUpOpen = true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Remove user&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Portal&lt;/span&gt; &lt;span class="na"&gt;target=&lt;/span&gt;&lt;span class="s"&gt;"#popup-target"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-show=&lt;/span&gt;&lt;span class="s"&gt;"isPopUpOpen"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Are you sure?&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"removeUser"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Yes&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"isPopUpOpen = false"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;No&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/Portal&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simples e fácil, não é? Agora, podemos manter nosso código estruturado corretamente, sem ser forçados a executar soluções desagradáveis ​​para mantê-lo funcionando!&lt;/p&gt;

&lt;p&gt;Se você ainda está curioso e deseja ver outros exemplos, &lt;a href="https://github.com/vuejs/vue-next/blob/46490ac1a5a7a20411affcd93877174c6dc007a7/packages/vue/examples/transition/modal.html"&gt;aqui&lt;/a&gt; você pode encontrar um pequeno site com uma modal, usando os portais do Vue 3. Você também pode procurar por &lt;a href="https://github.com/vuejs/vue-next/blob/957d3a0547e43ecf81169f5dd9663cf754ea7167/packages/runtime-core/__tests__/rendererPortal.spec.ts"&gt;cenários de teste&lt;/a&gt; no repositório &lt;code&gt;vue-next&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resumo
&lt;/h2&gt;

&lt;p&gt;Portal é uma das adições mais interessantes ​​do Vue 3. Simplifica o trabalho com elementos como modais e &lt;em&gt;popups&lt;/em&gt; e torna extremamente fácil renderizá-los sobre outros elementos do DOM sem soluções feias.&lt;/p&gt;




&lt;p&gt;Bom, mais uma tradução finalizada. Espero que tenha gostado. Não deixe de compartilhar este post para que mais pessoas sejam alcançadas por este conhecimento. Definitivamente, portais serão muito úteis em nosso dia-a-dia desenvolvendo com Vue.js.&lt;/p&gt;

&lt;p&gt;Até a próxima!&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Conheça as novas funcionalidades do Vue 3</title>
      <dc:creator>Emanuel Gonçalves</dc:creator>
      <pubDate>Mon, 20 Jan 2020 15:32:55 +0000</pubDate>
      <link>https://dev.to/codecasts/conheca-as-novas-funcionalidades-do-vue-3-o2g</link>
      <guid>https://dev.to/codecasts/conheca-as-novas-funcionalidades-do-vue-3-o2g</guid>
      <description>&lt;p&gt;Este texto é uma livre tradução do artigo do time do Vueschool sobre as novas funcionalidades que irão vir no Vue 3. Então, desde já agradecemos ao excelente artigo escrito por &lt;a href="https://twitter.com/filrakowski"&gt;Filip Rakowski&lt;/a&gt; que você pode &lt;a href="https://vueschool.io/articles/vuejs-tutorials/exciting-new-features-in-vue-3/"&gt;conferir aqui&lt;/a&gt;. Vamos ao texto?&lt;/p&gt;




&lt;p&gt;No antigo anterior, &lt;a href="https://vueschool.io/articles/vuejs-tutorials/faster-web-applications-with-vue-3/"&gt;nós aprendemos sobre as melhorias de performance que Vue 3 irá trazer&lt;/a&gt;. Nós já sabemos que apps escritos na nova versão do Vue irão performar melhor mas esta não é a melhor parte. O que mais importa para nós desenvolvedores é como esta nova &lt;em&gt;release&lt;/em&gt; irá afetar a forma como nós desenvolvemos.&lt;/p&gt;

&lt;p&gt;Como você poderia esperar, Vue 3 traz uma série de novas e emocionantes características. Felizmente, a equipe do Vue introduziu, em vez de grandes mudanças, adições e melhorias nas APIs atuais, para que as pessoas que já conhecem o Vue 2 se sintam à vontade rapidamente com as novas sintaxes.&lt;/p&gt;

&lt;p&gt;Vamos começar com a API, você provavelmente já ouviu falar a respeito...&lt;/p&gt;

&lt;h2&gt;
  
  
  Composition API
&lt;/h2&gt;

&lt;p&gt;Composition API é a &lt;em&gt;syntax feature&lt;/em&gt; mais discutida desta nova versão do Vue. É uma abordagem completamente nova para reuso de lógica e organização de código.&lt;/p&gt;

&lt;p&gt;Normalmente nós construímos nossos componentes com o que nós chamamos de &lt;em&gt;Options API&lt;/em&gt;. Para adicionar lógica aos componentes Vue nós preenchemos propriedades tais como &lt;code&gt;data&lt;/code&gt;, &lt;code&gt;methods&lt;/code&gt;, &lt;code&gt;computed&lt;/code&gt; etc. A maior desvantagem dessa abordagem é o fato de que esse não é como um código JavaScript em si. Você necessita saber exatamente quais propriedades estão acessíveis no templates assim como o comportamento do &lt;code&gt;this&lt;/code&gt;. Por baixo do capô, o compilador Vue precisa transformar estas propriedades em um código funcional. Por causa disso, nós não temos os benefícios de coisas como auto sugestões (autocomplete de editores) ou checagem de tipo (&lt;em&gt;type checking&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;A Composition API visa solucionar este problema, expondo os mecanismos atualmente disponíveis nas propriedades do componente como funções JavaScript. O &lt;em&gt;Core Team&lt;/em&gt; do Vue descreve a Composition API como "um conjunto de APIs baseadas em funções que permitem composições flexíveis de lógica de componentes". Código escrito usando a Composition API é mais legível e não há mágica por trás, o que faz com seja mais fácil de ler e aprender.&lt;/p&gt;

&lt;p&gt;Vamos ver um exemplo simples de um componente que usa a nova Composition API para entender como ela funciona:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"increment"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Count is: {{ count }}, double is {{ double }}, click to increment.
  &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onMounted&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;double&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;onMounted&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;component mounted!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;double&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;increment&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, vamos quebrar este código em algumas partes para entender o que está acontecendo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onMounted&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como mencionado antes, a Composition API expõe propriedades de componentes como funções, então a primeira etapa é importar as funções de que nós precisamos. Em nosso caso, precisamos criar uma referencia reativa com a função &lt;code&gt;ref&lt;/code&gt;, uma propriedade computada com &lt;code&gt;computed&lt;/code&gt; e acessar o &lt;em&gt;hook&lt;/em&gt; de ciclo de vida com &lt;code&gt;onMounted&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Agora, você provavelmente está se perguntando: o que é este misterioso método &lt;code&gt;setup&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em poucas palavras é apenas uma função que retorna propriedades e funções para o template. É só isso. Nós declaramos todas as propriedades reativas, propriedades computadas, &lt;em&gt;watchers&lt;/em&gt;, &lt;em&gt;hooks&lt;/em&gt; de ciclo de vida aqui e então retornamos eles para que possam ser usadas no template.&lt;/p&gt;

&lt;p&gt;O que não retornamos na função setup não estará disponível no template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No código acima nós declaramos uma propriedade reativa chamada &lt;code&gt;count&lt;/code&gt; usando a função &lt;code&gt;ref&lt;/code&gt;. Ela pode encapsular qualquer valor primitivo ou objeto e retorná-lo como uma propriedade. O valor passado será mantido na propriedade &lt;code&gt;value&lt;/code&gt; da referência criada. Por exemplo, se você quiser acessar o valor de &lt;code&gt;count&lt;/code&gt;, você precisa explicitamente chamar por &lt;code&gt;count.value&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;double&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... e isso é exatamente o que nós fazemos quando declaramos a propriedade computada &lt;code&gt;double&lt;/code&gt; e a função &lt;code&gt;increment&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;onMounted&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;component mounted!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com o &lt;em&gt;hook&lt;/em&gt; &lt;code&gt;onMounted&lt;/code&gt; nós estamos exibindo alguma mensagem quando o componente é montado só para mostrar para você que você pode 😉.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;double&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;increment&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No final estamos retornando as propriedades &lt;code&gt;count&lt;/code&gt; e &lt;code&gt;double&lt;/code&gt; com o método &lt;code&gt;increment&lt;/code&gt; para que eles estejam disponíveis no template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"increment"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Count is: {{ count }}, double is {{ double }}. Click to increment.
  &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E voila! Agora nós podemos acessar as propriedades e funções retornadas pelo método &lt;code&gt;setup&lt;/code&gt; no template da mesma forma que eles estavam declarados quando da antiga &lt;em&gt;Options API&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Este é um simples exemplo, que poderia ser facilmente realizado com a &lt;em&gt;Options API&lt;/em&gt;. O verdadeiro benefício da nova Composition API não é apenas desenvolver de uma forma diferente, os benefícios se revelam quando se trata de reutilizar nosso código/lógica.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reuso de código com a Composition API
&lt;/h3&gt;

&lt;p&gt;Há mais vantagens na nova Composition API. Vamos falar sobre reuso de código. Normalmente, se nós queremos compartilhar algum código entre componentes há duas opções disponíveis - &lt;em&gt;mixins&lt;/em&gt; e &lt;em&gt;scoped slots&lt;/em&gt;. Ambos tem suas desvantagens.&lt;/p&gt;

&lt;p&gt;Vamos dizer que nós queremos extrair uma funcionalidade chamada &lt;code&gt;counter&lt;/code&gt; e reaproveitá-la em outro componente. Abaixo, você pode ver como poderíamos fazer isso usando as APIs disponíveis e a nova Composition API:&lt;/p&gt;

&lt;p&gt;Vamos começar com &lt;em&gt;mixins&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;CounterMixin&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./mixins/counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;mixins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;CounterMixin&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A principal desvantagem dos mixins é o fato de nós não sabermos nada sobre o que eles estão adicionando ao nosso componente. Isso torna não apenas difícil de entender o código, mas também pode levar a colisões de nomes com propriedades e funções existentes.&lt;/p&gt;

&lt;p&gt;Agora os &lt;em&gt;scoped slots&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;Counter&lt;/span&gt; &lt;span class="na"&gt;v-slot=&lt;/span&gt;&lt;span class="s"&gt;"{ count, increment }"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
     {{ count }}
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"increment"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Increment&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt; 
  &lt;span class="nt"&gt;&amp;lt;/Counter&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com &lt;em&gt;scoped slots&lt;/em&gt; nós sabemos exatamente quais propriedades nós podemos acessar através da propriedade &lt;code&gt;v-slot&lt;/code&gt; então fica muito mais fácil entender o código. A desvantagem dessa abordagem é que podemos acessá-la apenas em um &lt;code&gt;template&lt;/code&gt; e estar disponível apenas no escopo do componente &lt;code&gt;Counter&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Agora, vamos ver como fica com a Composition API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;useCounter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;increment&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;incrememt&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;setup&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;increment&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useCounter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;increment&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Muito mais elegante não é? Nós não estamos limitados nem pelo &lt;code&gt;template&lt;/code&gt; nem pelo escopo dos nossos componentes e sabemos exatamente quais propriedades de &lt;code&gt;counter&lt;/code&gt; nós podemos acessar. Adicionado a isso, temos o benefício de termos auto complete do nosso código disponível em nosso editor pois &lt;code&gt;useCounter&lt;/code&gt; é apenas uma função que retorna algumas propriedades. Não há mágica por trás, então o editor pode nos ajudar com checagem de tipo e sugestões.&lt;/p&gt;

&lt;p&gt;Também é uma forma mais elegante de usarmos biblioteca de terceiros. Por exemplo, se nós queremos usar o &lt;a href="https://vuex.vuejs.org/"&gt;Vuex&lt;/a&gt; nós explicitamente usamos a função &lt;code&gt;useStore&lt;/code&gt; ao invés de poluir o protótipo do objeto Vue (&lt;code&gt;this.$store&lt;/code&gt;). Essa abordagem também apaga a mágica dos que acontece nos bastidores dos plug-ins Vue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se você quiser aprender um pouco mais sobre Composition API e seus casos de uso, eu recomendo fortemente ler &lt;a href="https://vue-composition-api-rfc.netlify.com/"&gt;este documento&lt;/a&gt; escrito pelo time do Vue que explica o raciocínio por trás da nova API e sugere os melhores casos de uso dela. Há também este &lt;a href="https://github.com/LinusBorg/composition-api-demos"&gt;excelente repositório&lt;/a&gt; com exemplos de uso da Composition API mantido por &lt;a href="https://twitter.com/linus_borg"&gt;Thorsten Lünborg&lt;/a&gt;, um membro do &lt;em&gt;core team&lt;/em&gt; do Vue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mudanças na API de montagem/configuração global
&lt;/h2&gt;

&lt;p&gt;Nós encontramos outra mudança grande na forma que nós instanciamos e configuramos nossa aplicação. Vamos ver como isso irá ficar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ignoredElements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;/^app-/&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mixin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;directive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;render&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;$mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Atualmente nós usamos o objeto global do Vue para nos prover qualquer configuração e criar novas instâncias do objeto Vue. Qualquer mudança feita num objeto Vue irá afetar todas as outras instâncias e componentes.&lt;/p&gt;

&lt;p&gt;Agora, vamos ver como isso irá funcionar no Vue 3:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createApp&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ignoredElements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;/^app-/&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mixin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;directive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como você provavelmente percebeu agora, todas as configurações têm o escopo definido para uma determinada aplicação Vue definida com a função &lt;code&gt;createApp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Atualmente, se alguma solução de terceiros estiver modificando o objeto Vue, ela poderá afetar sua aplicação de maneiras inesperadas (especialmente com &lt;em&gt;mixins&lt;/em&gt; globais), o que não será possível com o Vue 3.&lt;/p&gt;

&lt;p&gt;Esta mudança de API está sendo discutida atualmente &lt;a href="https://github.com/vuejs/rfcs/pull/29"&gt;neste RFC&lt;/a&gt;, o que significa que potencialmente poderá mudar no futuro.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fragments
&lt;/h2&gt;

&lt;p&gt;Outra emocionante adição que nós podemos esperar no Vue 3 são os fragmentos.&lt;/p&gt;

&lt;p&gt;O que são fragmentos? Bem, se você criar componentes Vue, eles só podem ter apenas um nó central.&lt;/p&gt;

&lt;p&gt;Isso significa que um componente como este não poderá ser criado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Hello&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;World&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A razão para isso é que a instância do Vue que representa qualquer componente Vue precisa ser vinculado a um único elemento DOM. A única forma que você tem para criar um componente com múltiplos nós DOM é criando um componente funcional que não tem fundamento na instância do Vue.&lt;/p&gt;

&lt;p&gt;Acontece que a comunidade React teve o mesmo problema. A solução que eles trouxeram foi criar um elemento virtual chamado &lt;code&gt;Fragment&lt;/code&gt;. Parece mais ou menos assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Columns&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Fragment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;td&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/td&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;td&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/td&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/React.Fragment&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apesar de &lt;code&gt;Fragments&lt;/code&gt; se parecerem com um elemento DOM normal eles são virtuais e não serão renderizados na árvore DOM. Dessa forma, podemos vincular a funcionalidade do componente em um único elemento sem criar um nó DOM redundante.&lt;/p&gt;

&lt;p&gt;Atualmente nós podemos usar &lt;code&gt;Fragments&lt;/code&gt; no Vue 3 com a biblioteca &lt;a href="https://vuejsdevelopers.com/2018/09/11/vue-multiple-root-fragments/"&gt;vue-fragments&lt;/a&gt; e no Vue 3 você os terá pronto para usar!&lt;/p&gt;

&lt;h2&gt;
  
  
  Suspense
&lt;/h2&gt;

&lt;p&gt;Outra grande ideia do ecossistema React que será adotado pelo Vue é o componente &lt;code&gt;Suspense&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Suspense&lt;/code&gt; suspenderá a renderização de seu componente e renderizará um componente &lt;em&gt;fallback&lt;/em&gt;* até que uma condição seja atingida. Durante a Vue London, Evan You tocou brevemente neste tópico e nos mostrou a API que mais ou menos podemos esperar. Acontece que o &lt;code&gt;Suspense&lt;/code&gt; será apenas um componente com slots:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Suspense&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;Suspended-component&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;#fallback&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Loading...
  &lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Suspense&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Um conteúdo de &lt;em&gt;fallback&lt;/em&gt;* será exibido até que o componente &lt;code&gt;Suspended-component&lt;/code&gt; seja inteiramente renderizado. &lt;code&gt;Suspense&lt;/code&gt; pode esperar até o download do componente, se for um componente assíncrono, ou executar algumas ações assíncronas na função &lt;code&gt;setup&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Múltiplos v-models
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;v-model&lt;/code&gt; é uma diretiva que nós usamos para realizar um &lt;em&gt;two-way data binding&lt;/em&gt; em um dado componente. Nós podemos passar uma propriedade reativa e modificá-la de dentro de um componente.&lt;/p&gt;

&lt;p&gt;Conhecemos bem o &lt;code&gt;v-model&lt;/code&gt; pelo seu uso em componentes de formulário.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"property /&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mas você sabia que pode usar o &lt;code&gt;v-model&lt;/code&gt; com cada componente? Por baixo do capô ele é apenas um atalho para um mecanismo de passar uma propriedade &lt;code&gt;value&lt;/code&gt; e ouvir um evento &lt;code&gt;input&lt;/code&gt;. Reescrevendo o exemplo acima para a sintaxe abaixo teremos o mesmo efeito:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; 
  &lt;span class="na"&gt;v-bind:value=&lt;/span&gt;&lt;span class="s"&gt;"property"&lt;/span&gt;
  &lt;span class="na"&gt;v-on:input=&lt;/span&gt;&lt;span class="s"&gt;"property = $event.target.value"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nós ainda podemos alterar o nome padrão das propriedades e os nomes dos eventos com a propriedade &lt;code&gt;model&lt;/code&gt; do componente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;checked&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;change&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como você pode ver a diretiva &lt;code&gt;v-model&lt;/code&gt; pode nos dar um açucar sintático muito útil quando queremos ter um &lt;em&gt;two-way data binding&lt;/em&gt; em nossos componentes. Infelizmente você só pode ter apenas um &lt;code&gt;v-model&lt;/code&gt; por componente.&lt;/p&gt;

&lt;p&gt;Felizmente, isso não será um problema no Vue 3! Você poderá dar nomes às propriedades do &lt;code&gt;v-model&lt;/code&gt; e ter quantas delas desejar. Abaixo você encontra um exemplo de dois &lt;code&gt;v-model&lt;/code&gt;s em um componente de formulário:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;InviteeForm&lt;/span&gt;
  &lt;span class="na"&gt;v-model:name=&lt;/span&gt;&lt;span class="s"&gt;"inviteeName"&lt;/span&gt;
  &lt;span class="na"&gt;v-model:email=&lt;/span&gt;&lt;span class="s"&gt;"inviteeEmail"&lt;/span&gt;
&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta mudança na API está atualmente sendo discutida &lt;a href="https://github.com/vuejs/rfcs/pull/31"&gt;neste RFC&lt;/a&gt; o que significa que potencialmente poderá mudar no futuro.&lt;/p&gt;

&lt;h2&gt;
  
  
  Portals
&lt;/h2&gt;

&lt;p&gt;Portais são componentes especiais determinados a renderizar certo conteúdo fora do componente atual. É também uma &lt;em&gt;feature&lt;/em&gt; &lt;a href="https://pl.reactjs.org/docs/portals.html"&gt;nativamente implementada no React&lt;/a&gt;. Isso é o que a documentação oficial do React diz sobre os portais:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Os portais fornecem uma maneira &lt;em&gt;first-class&lt;/em&gt; de renderizar filhos em um nó DOM que existe fora da hierarquia DOM do componente pai."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;É uma maneira muito interessante de lidar com modais, popups e outros componentes que geralmente aparecem no topo da página. Ao usar portais, você pode ter certeza de que nenhuma das regras CSS do componente pai afetará o componente que você deseja exibir e o isentará de executar hacks desagradáveis ​​com o &lt;code&gt;z-index&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para cada portal precisamos especificar qual o destino alvo onde o conteúdo do portal será renderizado. Abaixo você pode ver uma implementação da biblioteca &lt;a href="https://github.com/LinusBorg/portal-vue"&gt;portal-vue&lt;/a&gt; que adiciona essa funcionalidade ao Vue 2.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;portal&lt;/span&gt; &lt;span class="na"&gt;to=&lt;/span&gt;&lt;span class="s"&gt;"destination"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;This slot content will be rendered wherever thportal-target with name 'destination'
    is  located.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/portal&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;portal-target&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"destination"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!--
  This component can be located anywhere in your App.
  The slot content of the above portal component wilbe rendered here.
  --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/portal-target&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O Vue 3 terá suporte nativo aos portais!&lt;/p&gt;

&lt;h2&gt;
  
  
  Nova API para diretivas customizadas
&lt;/h2&gt;

&lt;p&gt;Diretivas customizadas irão mudar superficialmente no Vue 3 para melhor se alinhar com o ciclo de vida dos componentes. Esta mudança poderá tornar a API mais fácil de se entender e aprender para iniciantes, pois será mais intuitiva.&lt;/p&gt;

&lt;p&gt;Esta é a API atual:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyDirective&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;vnode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prevVnode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="nx"&gt;inserted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="nx"&gt;componentUpdated&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="nx"&gt;unbind&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... e isto é como ela irá se parecer no Vue 3:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyDirective&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;beforeMount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;vnode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prevVnode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="nx"&gt;mounted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="nx"&gt;beforeUpdate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="nx"&gt;updated&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="nx"&gt;beforeUnmount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="c1"&gt;// new&lt;/span&gt;
  &lt;span class="nx"&gt;unmounted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mesmo sendo uma &lt;em&gt;breaking change&lt;/em&gt;, ela deve ser facilmente coberta com uma ferramenta de compatibilidade do Vue.&lt;/p&gt;

&lt;p&gt;Esta mudança na API está atualmente sendo discutida &lt;a href="https://github.com/vuejs/rfcs/pull/32/files"&gt;neste RFC&lt;/a&gt; o que significa que potencialmente poderá mudar no futuro.&lt;/p&gt;

&lt;p&gt;Psst! Você pode aprender como dominar diretivas customizas em &lt;a href="https://vueschool.io/courses/custom-vuejs-directives"&gt;nosso curso&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sumário
&lt;/h2&gt;

&lt;p&gt;Além da Composition API, que é a maior e mais nova API do Vue 3, também podemos encontrar muitas melhorias menores. Podemos ver que o Vue está caminhando para uma melhor experiência de desenvolvimento e uma API mais simples e intuitiva. Também é bom ver que a equipe do Vue decidiu adotar muitas idéias que estão disponíveis atualmente apenas através de bibliotecas de terceiros para o núcleo do &lt;em&gt;framework&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A lista acima contém apenas as principais alterações e melhorias da API. Se você estiver curioso sobre outras, verifique o repositório de &lt;a href="https://github.com/vuejs/rfcs/"&gt;RFCs do Vue&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Bom, está é a tradução. Espero que tenha gostado. Não deixe de compartilhar este post para que mais pessoas o encontrem e se surpreendam com as mudanças bastante positivas que o time do Vue está trazendo.&lt;/p&gt;

&lt;p&gt;Até a próxima!&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Re-Lançamento do Acessibilidade for Devs</title>
      <dc:creator>Emanuel Gonçalves</dc:creator>
      <pubDate>Mon, 21 Oct 2019 20:52:42 +0000</pubDate>
      <link>https://dev.to/codecasts/re-lancamento-do-acessibilidade-for-devs-57l0</link>
      <guid>https://dev.to/codecasts/re-lancamento-do-acessibilidade-for-devs-57l0</guid>
      <description>&lt;p&gt;Fala! Tudo bem? Gostaria de compartilhar algo rapidamente com você.&lt;/p&gt;

&lt;p&gt;Você se interessa pelo assunto da acessibilidade? Você gostaria de deixar seus sites mais acessíveis, mas não sabe por onde começa? Você acha confuso aprender todas aquelas recomendações da W3C? Então te apresento um projeto um pouco velho (existe desde 2016) que pode te ajudar nisso. É o &lt;a href="https://acessibilidade-for-devs.github.io/"&gt;Acessibilidade for Devs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é o projeto?
&lt;/h2&gt;

&lt;p&gt;O Acessibilidade for Devs surgiu em 2016 como um guia de estudos escrito por mim para me orientar no desenvolvimento de aplicações web acessíveis. Na época eu criei uma &lt;a href="https://github.com/acessibilidade-for-devs"&gt;organização&lt;/a&gt; no Github com dois repositórios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O &lt;a href="https://github.com/acessibilidade-for-devs/acessibilidade-for-devs.github.io"&gt;guia&lt;/a&gt; em si.&lt;/li&gt;
&lt;li&gt;Um &lt;a href="https://github.com/acessibilidade-for-devs/forum"&gt;fórum&lt;/a&gt; no estilo do Front End BR com as perguntas sendo as ISSUES do Github.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Infelizmente, por uma falha minha, acabei não dando atenção no projeto na época, e assim ele ficou largado :(&lt;/p&gt;

&lt;p&gt;Porém, esta realidade está mudando. Recentemente eu reescrevi o site usando o &lt;a href="https://vuepress.vuejs.org/"&gt;Vuepress&lt;/a&gt; para facilitar a escrita do conteúdo (basta escrever em arquivos .md), criei algumas ISSUES com algumas melhorias pertinentes e estou precisando de você para dar uma ajuda neste trabalho.&lt;/p&gt;

&lt;h2&gt;
  
  
  O DNA do projeto
&lt;/h2&gt;

&lt;p&gt;Este projeto não visa competir com nenhum outro projeto para ajudar desenvolvedores a entender e desenvolver a acessibilidade em seus sites. Pelo contrário, ele &lt;strong&gt;é da comunidade para a comunidade&lt;/strong&gt;. O projeto vem para somar a esse movimento que já amadureceu muito desde 2016 quando eu comecei a me atentar a questão da acessibilidade.&lt;/p&gt;

&lt;h2&gt;
  
  
  No que eu posso ajudar?
&lt;/h2&gt;

&lt;p&gt;Há algumas formas de você ajudar este projeto:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Você encontrou algum problema no conteúdo? Um erro gramatical, por exemplo. Submeta seu PR com a correção.&lt;/li&gt;
&lt;li&gt;Você manja bastante de inglês? Pode ajudar com a tradução do conteúdo de português para inglês.&lt;/li&gt;
&lt;li&gt;Encontrou algum conteúdo novo sobre acessibilidade, algum tutorial bem bacana sobre o assunto? Contribua colocando ele no Guia, submetendo seu PR&lt;/li&gt;
&lt;li&gt;Existe algumas &lt;a href="https://github.com/acessibilidade-for-devs/acessibilidade-for-devs.github.io/issues"&gt;ISSUES&lt;/a&gt; no repositório. Se tiver condições de pegar uma para resolver também ajuda :)&lt;/li&gt;
&lt;li&gt;Por fim, mas não menos importante, se tiver alguma opinião em como o conteúdo pode ser organizado, pode submeter seu PR com a melhoria ou criar uma ISSUE com sua opinião. Sua crítica será muito bem vinda&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eu não sou um expert no assunto. Sou um curioso que pretende usar de sua curiosidade para aprender e facilitar o aprendizado de outras pessoas a respeito de um assunto tão importante em nossos dias.&lt;/p&gt;

&lt;p&gt;Espero que este texto possa ter despertado sua curiosidade para o projeto e não deixe de compartilhar, não apenas o texto, mas a organização no Github. Muito obrigado!&lt;/p&gt;




&lt;p&gt;Sou Emanuel, Engenheiro Front End e entusiasta de Inteligência Artificial. Maluco por séries e filmes. Amo programação e tudo que a cerca. Conheça meu trabalho no meu site &lt;a href="//emanuelgsouza.dev"&gt;emanuelgsouza.dev&lt;/a&gt; e em meu &lt;a href="https://github.com/emanuelgsouza"&gt;Github&lt;/a&gt;. May the force be with you!&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Aprendendo Ruby como um Dev JavaScript parte 1</title>
      <dc:creator>Emanuel Gonçalves</dc:creator>
      <pubDate>Fri, 13 Sep 2019 18:33:07 +0000</pubDate>
      <link>https://dev.to/codecasts/aprendendo-ruby-como-um-dev-javascript-parte-1-5hio</link>
      <guid>https://dev.to/codecasts/aprendendo-ruby-como-um-dev-javascript-parte-1-5hio</guid>
      <description>&lt;p&gt;Fala Codecaster!! Trazemos para você mais um texto aqui na Publicação do Codecasts. Hoje o tema é Ruby. A motivação de trazer este conteúdo é devido ao fato de que recentemente eu tenho buscado estudar um pouco essa linguagem, mais a título de conhecimento. Sendo assim, como um Desenvolvedor Web que lida a mais de 2 anos com JavaScript, preferi traçar paralelos com a linguagem que mais amo, e de quebra solidificar o conhecimento passando ele a diante. Espero que esta série de textos possam te despertar a curiosidade a respeito dessa linguagem.&lt;/p&gt;

&lt;h1&gt;
  
  
  O que é o Ruby?
&lt;/h1&gt;

&lt;p&gt;Bem, não é o foco deste texto trazer todo o conhecimento de Ruby e sua filosofia. É um texto mais prático. Porém, recomendo alguns conteúdos que podem ser úteis caso você queira aprender do zero a linguagem (como estou fazendo):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.caelum.com.br/apostila-ruby-on-rails"&gt;Apostila de Ruby on Rails da Caelum&lt;/a&gt; - sim preferi começar por essa apostila, por ter uma pegada mais prática&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=oEorhw5r2Do"&gt;A História de Ruby on Rails | Por que deu certo?&lt;/a&gt; - vídeo de uma das maiores referências de Ruby noo Brasil, Fábio Akita&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=kxXrWuCshUs"&gt;Vale a pena? Ruby on Rails (feat Akita e Lucas Caton)&lt;/a&gt; - vídeo do canal do pessoal do DevNaEstrada&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ruby-lang.org/pt/documentation/"&gt;Documentação oficial do Ruby&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://rubylearning.com/"&gt;Tutorial de Ruby&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Executando um código Ruby
&lt;/h2&gt;

&lt;p&gt;Bem, dedico uma seção aqui para deixar uma dica para você. Procure dar preferência, quando possível, a usar docker para execução de algumas coisas. Existem projetos, como o &lt;a href="https://github.com/tevun/dockerize"&gt;dockerize&lt;/a&gt;, em que você não precisa instalar nada na sua máquina para rodar um script, por exemplo. Foi o que eu fiz com o Ruby. Ele não vem instalado no Linux, e não gostaria de instalá-lo. Portanto, fiz uso o Docker. Segue os passos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# num terminal zsh&lt;/span&gt;
docker run &lt;span class="nt"&gt;--name&lt;/span&gt; ruby_exec &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;:/home &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/home ruby:slim ruby &amp;lt;script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para facilitar sua vida, você pode criar uma função no ZSH. Eu, por exemplo, criei uma chamada ruby, que ficou assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# em seu .zshrc&lt;/span&gt;
&lt;span class="k"&gt;function &lt;/span&gt;ruby&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  docker run &lt;span class="nt"&gt;--name&lt;/span&gt; ruby_exec &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;:/home &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="nt"&gt;-w&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/home ruby:slim ruby &lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa forma eu só digito no terminal &lt;code&gt;ruby script.rb&lt;/code&gt; e pronto, ele vai executar o script Ruby para mim.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando uma aplicação de terminal para cálculo de IMC
&lt;/h2&gt;

&lt;p&gt;Bem, o objetivo aqui é abordar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Saída padrão de dados usando &lt;code&gt;puts&lt;/code&gt; ou &lt;code&gt;print&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Entrada padrão de dados usando a função &lt;code&gt;gets&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Criação de sua própria função usando &lt;code&gt;def&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Entendendo a estrutura condicional&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Antes de mais nada, gostaria de convidá-lo a acessar o repositório meu de &lt;a href="https://github.com/emanuelgsouza/ruby-studies"&gt;estudos com ruby&lt;/a&gt;. O código para este texto é o &lt;a href="https://github.com/emanuelgsouza/ruby-studies/blob/master/imc.rb"&gt;imc.rb&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Saída de dados padrão
&lt;/h3&gt;

&lt;p&gt;Bem, como o texto fala de um programador com &lt;em&gt;background&lt;/em&gt; em JavaScript aprendendo Ruby, sabemos que em JavaScript a principal forma de saída é o famoso &lt;em&gt;console.log&lt;/em&gt;. Em Ruby, aprendemos que há duas formas principais de mostrar um dado na tela:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;puts&lt;/strong&gt;: printa e pula uma linha&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;print&lt;/strong&gt;: só printa o dado na tela, sem pular linha
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Hello World"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Entrada padrão de dados
&lt;/h3&gt;

&lt;p&gt;Em JavaScript, dependerá de onde estamos executando nosso código. Qual o contexto? Se for Node.js, por exemplo, teremos que capturar a entrada do usuário de uma forma não muito simples. Existem bibliotecas que nos ajudam nisso, &lt;a href="https://www.npmjs.com/package/prompts"&gt;prompts&lt;/a&gt; é uma delas.&lt;/p&gt;

&lt;p&gt;Já com Ruby, podemos fazer um simples gets, atribuindo para uma variável, que conseguimos capturar um &lt;code&gt;input&lt;/code&gt; do usuário.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# uso o print para que o promp para o usuário digitar o nome&lt;/span&gt;
&lt;span class="c1"&gt;# apareça no final da linha&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;"Qual o seu nome: "&lt;/span&gt;
&lt;span class="n"&gt;nome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;gets&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Criando sua própria função
&lt;/h3&gt;

&lt;p&gt;Para que eu consiga calcular o IMC, eu preciso da altura e peso da pessoa. Quando aprendemos a programar, aprendemos que código repetitivo colocamos em funções. Pois bem, precisamos criar uma função para mostrar um pergunta ao usuário e depois capturar a informação que ele digitar.&lt;/p&gt;

&lt;p&gt;Com JavaScript, podemos criar funções de inúmeras formas, com função nominal, função anônima ou &lt;em&gt;arrow functions&lt;/em&gt;. Já com Ruby, utilizamos a palavra reservada &lt;code&gt;def&lt;/code&gt;, bem semelhante ao Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_user_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;gets&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É importante notar que em Ruby usamos o &lt;a href="https://www.techotopia.com/index.php/Ruby_Methods"&gt;conceito de método&lt;/a&gt;, portanto, ao fazer suas pesquisas, se atente a essa nomenclatura.&lt;/p&gt;

&lt;h3&gt;
  
  
  Condicionais
&lt;/h3&gt;

&lt;p&gt;Por fim, a última parte da nossa abordagem é a categorização. Sabemos que o IMC possui categorias. Estaremos usando como referência &lt;a href="https://pt.wikipedia.org/wiki/%C3%8Dndice_de_massa_corporal"&gt;Wikipedia&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Para tanto, a decisão tomada foi criar uma função que retorna uma categoria a partir do IMC. Veja como ela ficou:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;categorize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"Muito abaixo do peso"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="mf"&gt;17.1&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="mf"&gt;18.49&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"Abaixo do peso"&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="mf"&gt;18.5&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="mf"&gt;24.99&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"Peso normal"&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="mf"&gt;29.99&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"Acima do peso"&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="mf"&gt;34.99&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"Obesidade I"&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="mf"&gt;39.99&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"Obesidade II (severa)"&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"Obesidade III (mórbida)"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Algumas coisas nos chamam a atenção em comparação com JavaScript:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O não uso de chaves &lt;code&gt;{}&lt;/code&gt; para delimitar blocos. Isso ocorre pelo uso da identação&lt;/li&gt;
&lt;li&gt;O uso da expressão &lt;code&gt;end&lt;/code&gt; para delimitar, também, o fim de um bloco de código&lt;/li&gt;
&lt;li&gt;E o range de dados, para delimitar um valor inicial e um valor final. Lindo demais :)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusões finais
&lt;/h2&gt;

&lt;p&gt;Como dito, o objetivo deste texto é proporcionar uma experiência muito prática e até superficial a respeito da linguagem Ruby em comparação com JavaScript. Espero que possa ser de auxílio em algum nível.&lt;/p&gt;

&lt;p&gt;Por fim, não deixe de conferir o &lt;a href="https://github.com/emanuelgsouza/ruby-studies/blob/master/imc.rb"&gt;código completo&lt;/a&gt; no meu repositório.&lt;/p&gt;

&lt;p&gt;Até a próxima!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>ruby</category>
    </item>
  </channel>
</rss>
