121 |
--------------------------------------------------------------------------------
/docs/tutorial/1-Iniciando com Vue/0-Antes de começar.md:
--------------------------------------------------------------------------------
1 | ## Antes de começar
2 |
3 | Bem-Vindo ao curso!Nosso objetivo é te oferecer todo o conteúdo introdutório para Vue em todos os aspectos possíveis.
4 |
5 | Para o curso, é necessario um bom conhecimento de HTML/CSS e especialmente JavaScript, devido ao fato do curso ser focado apenas na framework, e não na linguagem.
6 |
7 | Temas que serão abordados:
8 |
9 | - Vue
10 | - Vuetify
11 | - Vue Router
12 | - Vuex
13 | - Bibliotecas
14 | - Testes
15 | - Ecossistema
16 |
17 | Não se assuste, **depois de Vuex** não iremos aprofundar muito sobre as tecnologias, o intuito é você saber que aquilo existe no ecossistema Vue, dando uma noção geral para você conseguir se aprofundar no Vue :)
18 |
19 | ## Vue 3
20 |
21 | O curso foi feito para a versão 2.x, mas não se preocupe! o Vue 3 apenas acrescenta novos conteúdos, toda a base do vue continua sendo a mesma!
22 |
23 | [Ir para Próxima Seção](./1-O%20que%20e%20Vue.md)
24 |
--------------------------------------------------------------------------------
/docs/tutorial/1-Iniciando com Vue/1-O que e Vue.md:
--------------------------------------------------------------------------------
1 | # Vue
2 |
3 | Sejam bem vindos ao paper de Vue da [He4rt Developers](discord.io/He4rt), aqui nós iremos dar uma introdução ao framework **Vue**, mostrando todo o seu conceito e mostrando como utilizar de maneira efetiva.
4 |
5 | O **Vue**(se pronuncia **view**) é um framework para a construção de sites de forma progressiva, sendo diferente de outros tipo de estrutura monolítica. O ecossistema do **Vue** é extenso possibilitando ao desenvolvedor construir aplicações Frontend Web.
6 |
7 | ## Comunidade
8 |
9 | A comunidade do **Vue** vem crescendo cada vez mais, iremos estar disponibilizando alguns links da comunidade para auxiliar seu estudo sobre a framework.
10 |
11 | [Fórum](https://forum.vuejs.org)
12 |
13 | [VueJSBrasil](http://vuejs-brasil.com.br/)
14 |
15 | [VueSchool](https://vueschool.io/)
16 |
17 | [VueMastery](https://www.vuemastery.com)
18 |
19 | [MadeWithVue](https://madewithvuejs.com)
20 |
21 | [LearnVue](https://twitter.com/LearnVuejs2)
22 |
23 | ## SPA(Single Page Aplication)
24 |
25 | Significa que no **Vue** teremos uma aplicação web completa acontecendo em uma única página sem a necessidade de recarregar a página. O **Vue** também possui **SSR(Server Side Render)** com o **Nuxt** e aplicações **PWA** com o **Quasar**, mas neste início vamos focar apenas no **SPA** e apresentar alternativas futuramente.
26 |
27 | Utilizando este conceito conseguimos construir aplicações frontend de forma robusta e escalável.
28 |
29 | ## Virtual DOM
30 |
31 | Virtual DOM é um framework para manipulação do DOM(Document Object Model) que é utilizado pelo **Vue**, ele faz uma representação do DOM real na linguagem JavaScript, ou seja, o DOM verdadeiro é gerado a partir do DOM Virtual.Por conta disso, o **Vue** utiliza o **vue-loader** para fazer todo o ciclo do Virtual DOM e conseguir transformar no DOM final.
32 |
33 | ## VueLoader
34 |
35 | O **vue-loader** irá analisar o arquivo, pegar cada bloco de linguagem e montá-lo de volta em um módulo CommonJs cujo module.exports seja um objeto de opções do componente **Vue.js**.
36 |
37 | Para manipular, o **Vue** utiliza um sistema de componentes com a extensão **.vue**. O arquivo é um formato de arquivo personalizado que usa a sintaxe parecido com o HTML para descrever um componente Vue. Cada arquivo é dividido em três partes: `,
49 |
50 |
55 | ```
56 |
57 | [Próxima Seção](./2-VueCLI.md)
58 |
--------------------------------------------------------------------------------
/docs/tutorial/1-Iniciando com Vue/2-VueCLI.md:
--------------------------------------------------------------------------------
1 | # Vue CLI
2 |
3 | Neste tutorial iremos utilizar **vue-cli** para a criação do nosso projeto, pois ele irá facilitar a instalação de plugins além de ter uma interface agradável.
4 |
5 | Primeiramente, abre o terminal para instalar o **vue-cli**
6 |
7 | ```sh
8 | yarn global add @vue/cli
9 | # ou por npm
10 | npm install -g @vue/cli
11 | ```
12 |
13 | Agora para verificar se o cli foi instalado:
14 |
15 | ```sh
16 | vue --version
17 | ```
18 |
19 | Podemos criar o nosso projeto de duas formas:
20 |
21 | ```sh
22 | vue create
23 | ```
24 |
25 | Ou podemos usar a UI:
26 |
27 | ```sh
28 | vue ui
29 | ```
30 |
31 | * O cli irá criar o projeto na onde o comando foi usado, certifique-se que está na pasta correta
32 |
33 | Usando o comando `vue create vue4noobs` teremos a seguinte tela:
34 |
35 |
36 |
37 |
38 |
39 | Vamos escolher a **default**, mas se quiser dar uma olhada no que o cli pode acrescentar no seu projeto escolhendo a opção manual, fique a vontade!
40 |
41 | Quando a instalação dos pacotes for concluida, execute os comandos:
42 |
43 | ```sh
44 | cd vue4noobs
45 | yarn serve
46 | ```
47 |
48 | Assim que o servidor terminar de ligar, aparece o **localhost** disponível para acessar a aplicação:
49 |
50 |
51 |
52 |
53 | Agora acessamos o **localhost** e teremos a página inicial do projeto gerado pelo CLI:
54 |
55 |
56 |
57 |
58 | Na próxima seção iremos explicar todos os arquivos que estão no projeto, nos vemos lá!
59 |
60 | [Próxima Seção](./3-Estrutura%20do%20Projeto.md)
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/docs/tutorial/1-Iniciando com Vue/3-Estrutura do Projeto.md:
--------------------------------------------------------------------------------
1 | # Estrutura do Projeto
2 |
3 | Agora iremos explicar sobre cada arquivo que contém no projeto. Se você optou pela opção **default**, os arquivos serão os seguintes:
4 |
5 | ```
6 | .
7 | ├── node_modules # Dependências do projeto
8 | ├── public # Todos os arquivos públicos do projeto
9 | | └── favicon.icon # Ícone do projeto
10 | | └── index.html # HTML principal da aplicação
11 | ├── src # Pasta source do projeto
12 | | └── assets # Todos os assets do projetos
13 | | └── components # Componentes do vue
14 | | └── App.vue # Componente principal da aplicação
15 | | └── main.js # Arquivo de montagem do componente
16 | ├── .gigignore # Arquivos que vão ser ignorados pelo Git
17 | ├── babel.config.js # Configurações do babel
18 | ├── package.json # Settings do projeto
19 | ├── yarn.lock # Se estiver usando yarn
20 | ```
21 |
22 | ## public/favicon.icon
23 |
24 | Ícone do seu site.
25 |
26 | ## public/index.html
27 |
28 | É a onde o virtual DOM irá transformar no DOM final, anexando no html.
29 |
30 | ## src/assets/**
31 |
32 | Todas as imagenss e presets serão guardados aqui.
33 |
34 | ## src/components/**
35 |
36 | Todos os componentes da aplicação ficarão aqui, as **rotas** normalmente ficam em uma pasta **pages** ou **views**, iremos abordar isso futuramente.
37 |
38 | ## src/App.vue
39 |
40 | O componente base da aplicação. Normalmente, a rota inicial de nosso projeto terá o conteúdo neste Arquivo, pois é ele que sera o "intermediador" principal da aplicação.
41 |
42 | * Quando usarmos o [VueRouter](https://router.vuejs.org/) este arquivo vira o **view-router** principal. Sobre o **VueRouter**, recomendamos estar sobre apenas quando acabar sobre o básico do **Vue** para não confundir conceitos.
43 |
44 | ## src/main.js
45 |
46 | Arquivo de entrada principal, criando a [Instância](https://br.vuejs.org/v2/guide/instance.html) do **Vue** e anexando na div que possui o id **app**, que fica no **public/index.html**.
47 |
48 | * Todas as bibliotecas poderão ser anexadas antes da criação da instância(new Vue) neste arquivo.
49 |
50 | ## babel.config.js
51 |
52 | O [babel](https://babeljs.io/) é um transcompilador de JavaScript para converter códigos ES6+, assim mecanismos mais antigos conseguindo executar o código.
53 |
54 | Na próxima seção irá ser explicado como está o fluxo inicial da aplicação e introduzindo o conceito de **props**.
55 |
56 | [Próxima Seção](./4-Fluxo%20e%20Props.md)
--------------------------------------------------------------------------------
/docs/tutorial/1-Iniciando com Vue/4-Fluxo e Props.md:
--------------------------------------------------------------------------------
1 | # Fluxo e Props
2 |
3 | Agora vamos falar sobre o **App.vue** e a propriedade **HelloWorld.vue**:
4 |
5 | ```html
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
23 |
24 |
34 | ```
35 |
36 | ## Elemento Raiz
37 |
38 | Vamos começar pelo template, a **div** é necessaria pois o **template** pode ter apenas um item em sua raiz:
39 |
40 | Correto:
41 |
42 | ```html
43 |
44 |
45 |
57 |
58 | ```
59 |
60 | O **HelloWorld** é um componente que está sendo importado por outro componente **App.vue**, para isso, precisamos registrar o componente:
61 |
62 | ```html
63 |
72 | ```
73 |
74 | ## Convensões de Importanção
75 |
76 | * Curiosidade: O **Vue** reconhece tanto **PascalCase** quanto **kebab-case** e vice-versa, exemplo:
77 |
78 | ```html
79 |
80 |
81 |
82 |
83 |
92 | ```
93 |
94 | ## Nome do Componente
95 |
96 | O **name** significa o nome do componente que está sendo exportado, por padrão o **Vue** exporta o nome que está descrito na extensão do arquivo, neste caso, **App** seria exportado da mesma forma.
97 |
98 | ```js
99 |
104 | ```
105 |
106 | ## Propriedades
107 |
108 | Agora vamos diretamente para o componente **HelloWorld.vue**:
109 |
110 | ```js
111 |
112 |
113 |
{{ msg }}
114 |
115 | For a guide and recipes on how to configure / customize this project,
116 | check out the
117 | vue-cli documentation.
118 |
141 |
142 |
143 |
151 | ```
152 |
153 | Vamos desconsiderar as listas, pois possuem apenas a lógica padrão do **HTML**, vamos focar no que o **Vue** disponibiliza:
154 |
155 | ```js
156 |
157 |
158 |
{{ msg }}
159 |
160 |
161 |
162 |
169 | ```
170 |
171 | Primeiramente, uma **propriedade** (props) está sendo exportada, e dentro deste objeto temos a declaração de uma prop com o nome **msg**, tendo o tipo **obrigatório** String.
172 |
173 | Dessa forma, podemos atribuir um conteúdo de um componente **pai** para o componente **filho**, assim seguindo o conceito de **componentização**.
174 |
175 | No caso de **App.vue**, estamos passando a **msg** com o tipo **String**.
176 |
177 | ```html
178 |
179 | ```
180 |
181 | Como obrigatoriamente indicamos que **msg** precisa ser uma **String**, se passarmos:
182 |
183 | ```html
184 |
185 | ```
186 |
187 | Irá gerar o erro, pois estamos passando um **Number**, e não uma **String**.
188 |
189 | * O **v-bind** pertence ao conceito de diretivas do **Vue**, o que estamos fazendo é ao **Vue** reconhecer o que passamos como um número e não como string, por exemplo:
190 |
191 | ```html
192 |
193 | ```
194 |
195 | Neste caso, estariamos passando um **Object**. Iremos futuramente no curso explicar o que são as diretivas, então não se preocupe :)
196 |
197 | * Podemos também passar para as **props** outras restrições, como **required**(boolean, se a prop será obrigatória ou não), **default**(podemos definir um valor setado em caso o componente pai não mande nenhum conteúdo da prop setada).
198 |
199 | ```js
200 |
210 | ```
211 |
212 | Agora vamos falar sobre a **msg** sendo exibida no template
213 |
214 | ```js
215 |
216 |
217 |
{{ msg }}
218 |
219 |
220 | ```
221 |
222 | ## Interpolação
223 |
224 | A forma de exibir conteúdo da exportação no template chamamos de **interpolação**, passando dois abre e fecha conchete para representar
225 |
226 | ```html
227 | {{ }}
228 | ```
229 |
230 | No **Vue**, conteúdos passados por **interpolação** já são reativos, ou seja, se no **componente-pai** a **msg** for alterada durante a execução do DOM, o que está sendo exibido no template, mesmo por meio de **propriedade**, irá ser automaticamente trocada pelo novo conteúdo.
231 |
232 | * Em caso de entrada de dados, este comportamente é diferente.
233 |
234 | Podemos também intercalar conteúdos **estáticos** sem nenhum problema
235 |
236 | ```js
237 |
238 |
239 |
Hello {{ world }}
240 |
241 |
242 |
243 |
254 | ```
255 |
256 | Recomendados que dê uma olhada melhor sobre a sintaxe dos [templates](https://br.vuejs.org/v2/guide/syntax.html#Texto).
257 |
258 | Nos próximos capítulos, iremos introduzir conceitos do **Vue**, como **data**, **methods**, **computed** e **watch**, esperamos te ver lá :)
259 |
260 | [Próxima Seção](./5-Componentização.md)
261 |
--------------------------------------------------------------------------------
/docs/tutorial/1-Iniciando com Vue/5-Componentização.md:
--------------------------------------------------------------------------------
1 | # Componentização
2 |
3 | Resumindo: `Se você está copiando código, falta componentização.`
4 |
5 | Agora falando um pouco mais sério:
6 |
7 | Um componente é algo que sozinho tem um sentido, ele pode ser único, ou um conjunto de vários outros components.Por exemplo, o cabeçalho de um site ele é unico, por mais que pode variar quando o usuario ta logado/deslogado, ele continua sendo um cabeçalho, então continua possuindo um único sentido.
8 |
9 | A vantagem da componentização é a reutilização de código e padronização, pois se for necessário alguma alteração no cabeçalho, por exemplo, não teremos que procurar todos os cabeçalhos na aplicação inteira.
10 |
11 | É comum que um aplicativo seja organizado em uma árvore de componentes aninhados de forma parecido com uma [Árvore](https://pt.wikibooks.org/wiki/Algoritmos_e_Estruturas_de_Dados/%C3%81rvore):
12 |
13 |
14 |
15 |
16 |
17 | Na próxima seção iremos iniciar o estudo dos conceitos do vue, mostrando as suas vantagens em relação ao VanillaJS.
18 |
19 | [Próxima Seção](../2-Conceitos/1-Data,%20Methods%20e%20Modificadores.md)
--------------------------------------------------------------------------------
/docs/tutorial/2-Conceitos/1-Data, Methods e Modificadores.md:
--------------------------------------------------------------------------------
1 | # Data
2 |
3 | É o objeto de dados para a instância do Vue. O Vue converterá recursivamente suas propriedades em getters e setters para torná-lo "reativo". O objeto deve ser simples: objetos nativos, como objetos de API do navegador e propriedades de protótipo, são ignorados. Uma regra prática é que os dados devem ser apenas dados - não é recomendável observar objetos com seu próprio comportamento estável.
4 |
5 | Agora vamos declarar o **data**
6 |
7 | ```js
8 |
17 | ```
18 |
19 | Dessa forma, declaramos **contador** de uma forma reativa, como fala na seção passado, se **contador** for passado para uma **propriedade** e o valor de **contador** mudar, o que está sendo exibido na **propriedade** também irar mudar.
20 |
21 | Precisamos retornar um objeto para o **data** para que cada instância possa manter uma cópia independente do objeto de dados retornado, assim mantendo a "reatividade".
22 |
23 | No **data** podemos declarar qualquer tipo de dado(objetos, arrays, etc...)
24 |
25 | ```js
26 |
39 | ```
40 |
41 | A sintaxe do **Vue** em tudo que está dentro do **export default** é baseado nos [objetos literais](https://tableless.com.br/javascript-objetos-literais-vs-funcoes-construtoras/).
42 |
43 | ---
44 |
45 | Na seção de **props**, passamos a string de maneira estática, mas também podemos passar dados diretamente no template:
46 |
47 | ```html
48 |
49 |
50 |
51 |
61 | ```
62 |
63 | ---
64 |
65 | O **Vue** permite executar expressões JavaScript diretamente no template:
66 |
67 | ```html
68 |
{{ concluido ? 'SIM' : 'NÃO' }}
69 | ```
70 |
71 | * No caso **concluido** pertence ao **data()**.
72 | * Atribuições e controle de fluxo **NÃO** funcionam.
73 |
74 | ---
75 |
76 | Podemos também preencher o que temos no **data** com dados **assíncronos** usando [LifeCycleHooks](https://br.vuejs.org/v2/guide/instance.html#Diagrama-do-Ciclo-de-Vida), mas iremos abordar esse tema mais para a frente pois precisamos ver alguns outros conceitos do **Vue** primeiramente.
77 |
78 | ## Methods
79 |
80 | Métodos que vão juntar na instância do Vue. Você pode acessar esses métodos diretamente na instância do vue ou usá-los em expressões de diretiva. Todos os métodos terão esse contexto automaticamente vinculado à instância do Vue. O funcionamento de um **método** é basicamente ao de uma **função**, diferenciando de uma **computed** que será explicado na próxima seção.
81 |
82 | Agora, vamos fazer um **contador** mutando a nossa variavel declarada na instância, usando **methods**:
83 |
84 | ```js
85 |
86 |
87 |
88 |
116 |
117 |
118 |
119 |
136 | ```
137 | Podemos também capturar o **event**, contendo todos os dados do emissor, ou seja, o evento do DOM nativo:
138 |
139 | ```js
140 |
149 | ```
150 |
151 | ---
152 |
153 | Como dito na seção de fluxo e props, podemos exibir algo da instância diretamente no template.No methods podemos retornar valores para o template usando o **v-bind**.
154 |
155 | ```js
156 |
157 |
158 |
159 |
160 |
169 | ```
170 |
171 | ## Modificadores
172 |
173 | Para acessar variáveis que estão na instância do **data**, precisamos usar o **this**, como está sendo usado no **this.contador++**.
174 |
175 | Usando o **v-on** podemos escutar eventos do DOM (parecido com o funcionamento do eventListener)
176 |
177 | O **Vue** disponibiliza **modificadores de eventos** para evitar a propagação:
178 |
179 | ```html
180 | .stop
181 | .prevent
182 | .capture
183 | .self
184 | .once
185 | .passive
186 | ```
187 |
188 | Por exemplo:
189 |
190 | ```html
191 |
192 | ```
193 |
194 | Dessa forma, o submit não irá carregar a página devido ao **prevent**
195 |
196 |
197 | Lembrando que a sintaxe sem o **()** também é valida:
198 |
199 | ```html
200 |
201 | ```
202 |
203 | Também podemos acessar modificadores de teclado, como por exemplo:
204 |
205 | ```html
206 |
207 | ```
208 |
209 | ```html
210 | .enter
211 | .tab
212 | .delete
213 | .esc
214 | .space
215 | .up
216 | .down
217 | .left
218 | .right
219 | ```
220 |
221 | ---
222 |
223 | Existe uma convensão de sintaxe para simplificar o **v-bind** e **v-on**
224 |
225 | **v-on** é substituido por **@**
226 | **v-bind** é simplificado apenas para **:**
227 |
228 | ```html
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
245 | ```
246 |
247 | Mais sobre modificadores [aqui](https://br.vuejs.org/v2/guide/events.html#Modificadores-de-Evento)
248 |
249 | ---
250 |
251 | Na próxima seção, iremos introduzir formas de manipular o que será renderizado no DOM Virtual com **v-if** e **v-for**, esperamos te ver la!
252 |
253 | [Próxima Seção](./2-Diretivas.md)
--------------------------------------------------------------------------------
/docs/tutorial/2-Conceitos/10-Mixins.md:
--------------------------------------------------------------------------------
1 | # Mixins
2 |
3 | Quando o seu projeto Vue começar a crescer, você pode copiar e colar os mesmos dados, métodos e observadores repetidamente, se tiver componentes semelhantes. Esse tipo de ideia "quebra" a componentização que uma framework oferece, por isso **mixins** são úteis. Claro, você pode escrever todos esses **arquivos separados** como um único componente e usar adereços para tentar personalizá-los, mas o uso desses adereços pode facilmente ficar **confuso**.
4 |
5 | Incrivelmente existe muitos códigos que ainda são feito com o famoso ctrc + ctrv de um componente a outro, então **recomendamos fortemente** o seu aprendizado com mixins para melhor utilização da framework.
6 |
7 | Felizmente, os **Mixins** do **Vue** são bem simples de se usar (assim como a maioria das coisas no **Vue** comparando com outras frameworks).O componente terá acesso a todas as opções no mixin como se fosse declarado no próprio componente.
8 |
9 | ```js
10 | // arquivo mixin.js
11 | export default {
12 | data () {
13 | idade: 18
14 | },
15 | created() {
16 | console.log('Mixin existe!');
17 | },
18 | methods: {
19 | mostrarIdade() {
20 | console.log('Agora printando de uma função do mixin!');
21 | }
22 | }
23 | }
24 |
25 | // arquivo main.js
26 | import mixin from './mixin.js'
27 |
28 | new Vue({
29 | mixins: [mixin],
30 | created() {
31 | console.log(this.$data);
32 | this.mostrarIdade();
33 | }
34 | });
35 | // "Mixin existe!"
36 | // { idade: 18 }
37 | // "Agora printando de uma função do mixin!"
38 | ```
39 |
40 | Dessa forma, temos acesso ao mixin apenas pelo **$data**, evitando problemas com declarações no próprio componente que está utilizando o **mixin**.
41 |
42 | ```js
43 | // mixin.js file
44 | export default {
45 | data () {
46 | return {
47 | title: 'pertenco ao mixin'
48 | }
49 | }
50 | }
51 | // -----------------------------------------------------------
52 |
53 | // main.js file
54 | import mixin from './mixin.js';
55 | export default {
56 | mixins: [mixin],
57 | data() {
58 | return {
59 | title: '>NÃO< estou no mixin'
60 | }
61 | },
62 | created() {
63 | console.log(this.title);
64 | }
65 | }
66 | // => ">NÃO< pertenco ao mixin"
67 | ```
68 |
69 | # Mixins Globais
70 |
71 | Podemos criar mixins globais utilizando o **Vue.mixin**:
72 |
73 | ```js
74 | // irá jogar o 'importante' para as opções
75 | Vue.mixin({
76 | created() {
77 | const importante = this.$options.importante;
78 | if (importante) {
79 | console.log(importante);
80 | }
81 | }
82 | })
83 |
84 | new Vue({
85 | importante: 'he4rt'
86 | });
87 | // "he4rt"
88 | ```
89 |
90 | * Quando for criar mixins globais, tome muito cuidado pelo fato de ser algo global que estará na instância sempre.
91 |
92 | Na próxima seção, iremos ensinar a como utilizar os pre-processadores no **Vue**.
93 |
94 | [Próxima Seção](./11-Pre-Processadores.md)
95 |
--------------------------------------------------------------------------------
/docs/tutorial/2-Conceitos/11-Pre-Processadores.md:
--------------------------------------------------------------------------------
1 | # Pre-Processadores
2 |
3 | Nas seções de introdução, demos o exemplo que no **Vue** é possível utilizar pre-processadores de forma facilitada, agora iremos explicar como implementar:
4 |
5 | * Nas opções de criação do projeto manual usando o **VueCLI**, é possível adicionar os pre-processadores diretamente por lá.
6 |
7 | ## SCSS - SASS
8 |
9 | Vamos instalar primeiramente as dependências necessárias:
10 |
11 | ```zsh
12 | yarn add sass-loader sass --save-dev
13 | ```
14 |
15 | Dessa forma, podemos agora utilizar o sass:
16 |
17 | ```vue
18 |
21 | ```
22 |
23 | Para essa estilização se manter apenas no seu escopo, é necessário que você adicione o `scoped` no seu `style`:
24 |
25 | ```vue
26 |
29 | ```
30 |
31 | Dessa maneira o estilo que for escrito aqui não passara para outro componente.
32 |
33 | Caso a estilização do seu componente se torne grande ou você deseja organizar melhor seus estilos é possível criar um arquivo `.scss` adicionamos como dependência:
34 |
35 | ```vue
36 |
37 | ```
38 |
39 | ## PugJS
40 |
41 | ```zsh
42 | yarn add pug --save-dev
43 | ```
44 |
45 | ```html
46 |
47 | main
48 | h1 {{ hello }}
49 |
50 | ```
51 |
52 | Na próxima seção, iremos para as nossas considerações de tudo oque aprendemos sobre os conceitos base do **Vue**, te vemos lá!
53 |
54 | [Próxima Seção](./12-SCSS.md)
55 |
--------------------------------------------------------------------------------
/docs/tutorial/2-Conceitos/13-SCSS-Avançado.md:
--------------------------------------------------------------------------------
1 | # SCSS Avançado
2 |
3 | Nessa seção vamos abordar alguns conceitos mais avançados do SCSS, como extend, placeHolders, module mode e arquitetura de pastas.
4 |
5 | ## Extend
6 |
7 | O extend é um recurso em que você replica o mesmo estilo de uma classe em outra.
8 |
9 | Mas qual a diferença entre o @mixin e o @extend?
10 |
11 | O mixin vai gerar uma copia daquele estilo em outro componente na hora da compilação.
12 | Já o extends gera uma referência para a classe original.
13 |
14 | > Mixin
15 |
16 | ```scss
17 | /// Mixin input
18 |
19 | @mixin placeHolder {
20 | display: -webkit-box;
21 | display: -ms-flexbox;
22 | display: -webkit-flex;
23 | display: flex;
24 | }
25 | .classe1 {
26 | @include placeholder;
27 | }
28 | .classe2 {
29 | @include placeholder;
30 | }
31 |
32 | /// Mixin output
33 | .classe1 {
34 | display: -webkit-box;
35 | display: -ms-flexbox;
36 | display: -webkit-flex;
37 | display: flex;
38 | }
39 | .classe2 {
40 | display: -webkit-box;
41 | display: -ms-flexbox;
42 | display: -webkit-flex;
43 | display: flex;
44 | }
45 | ```
46 |
47 | > Extend
48 |
49 | ```scss
50 | /// Extend input
51 | %placeHolder {
52 | display: -webkit-box;
53 | display: -ms-flexbox;
54 | display: -webkit-flex;
55 | display: flex;
56 | }
57 |
58 | .classe1 {
59 | @extend %placeHolder;
60 | }
61 |
62 | .classe2 {
63 | @extend %placeHolder;
64 | }
65 |
66 | /// Extend output
67 | .classe1,
68 | .classe2 {
69 | display: -webkit-box;
70 | display: -ms-flexbox;
71 | display: -webkit-flex;
72 | display: flex;
73 | }
74 | ```
75 |
76 | Apesar do @extend ser mais simples, ele é tão poderoso quanto @mixin. Mas isso pode causar alguns problemas.
77 |
78 | Como a classe `%placeHolder` é copiada para duas classes, elas são independentes e não se comportam como se fossem uma única classe.
79 | Dependendo do comportamento da classe, a classe pai pode não ser a classe original.
80 |
81 | ### Quando usar ou não o @extend?
82 |
83 | - Mixin: Utilize para gerar seu código de modo dinâmico através de variáveis;
84 | - Extend: Utilize para elementos comuns mas que haverá pouca repetição;
85 | - Quando for necessário criar algum tipo de automatização utilize o @mixin, caso contrario utilize o @extend, ou até mesmo os dois juntos.
86 |
87 | ## PlaceHolders
88 |
89 | PlaceHolders ou seletores fantasmas são como classes, porém, não são geradas no CSS final. Eles são utilizados para reutilizar propriedades de um seletor em outro.
90 |
91 | Para poder aplicar isso, precisamos utilizar o `@extend`:
92 |
93 | ```scss
94 | // _card.scss
95 |
96 | %default-border-style {
97 | border: 1px solid #ccc;
98 | border-radius: 5px;
99 | }
100 |
101 | .card {
102 | @extend %default-border-style;
103 | padding: 10px;
104 | background-color: #ccc;
105 | }
106 |
107 | .card__button {
108 | @extend %default-border-style;
109 | background-color: #ccc;
110 | }
111 | ```
112 |
113 | Os placeholders são muito úteis para reutilizar estilos no contexto do seu componente.
114 |
115 | ## Module Mode
116 |
117 | A uns anos atrás foi lançado um feature no scss que é chamado de scss modules basicamente ela permite que o seu estilo funcione como um modulo da aplicação assim liberando alguns recursos interessantes.
118 |
119 | Existem duas formas de se utilizar o sass module:
120 |
121 | `nome.module.scss` ou `_nome.scss`
122 |
123 | Nas duas formas você vai poder usufruir de todos os recursos do sass module.
124 |
125 | As novidades que vieram foi justamente o ***@use*** que permite que você importe um arquivo de estilo dentro de outro, para ser utilizado naquele contexto.
126 |
127 | ***@foward*** que permite que você importe um arquivo de estilo dentro de outro e que ele seja passado para frente na importação.
128 |
129 | ### Porque o *@import* é um problema ?
130 |
131 | Usando o ***@import*** no scss encontramos um problema, um arquivo que possui por exemplo `margin: 5rem;` no final pode ficar com `margin: 10rem;`, caso tenha alguma variável com o mesmo nome da qual alimenta aquela propriedade, visto que o ***@import*** na hora da compilação leva em consideração a ordem.
132 |
133 | EXAMPLE:
134 |
135 | ```scss
136 | @import "spacings"; // margin: 10rem;
137 | @import "variables";// margin: 5rem;
138 | @import "mixins";
139 | @import "colors";
140 |
141 |
142 | .container {
143 | margin: var(--margin); // essa margin vem do variables
144 | }
145 | ```
146 |
147 | Caso a gente altere a ordem de importação, na hora que ocorrer a compilação será alterado o valor.
148 |
149 | ```scss
150 | @import "variables";// margin: 5rem;
151 | @import "spacings"; // margin: 10rem;
152 | @import "mixins";
153 | @import "colors";
154 |
155 |
156 | .container {
157 | margin: var(--margin); // essa margin vem do spacings
158 | }
159 | ```
160 |
161 | O sass compila de forma procedural, ou seja, o valor da propriedade vai ser alterado de acordo com a última variável encontrada.
162 |
163 | ### O problema que o ***@use*** e ***@foward*** resolve
164 |
165 | #### @foward
166 |
167 | Ele é similar ao @import, você vai passar para frente oque estiver em um contexto, não haverá sobre escrita. O ***@foward*** levará somente estruturas não complexas. Funções, mixins e blocos condicionais não serão levados para frente.
168 |
169 | #### @use
170 |
171 | É utilizado no contexto e recebe um namespace, então se o meu arquivo se chama util tudo que eu utilizar ali será necessário passar o util como prefixo.
172 |
173 | EXAMPLE:
174 |
175 | ```scss
176 | @use "_util";
177 |
178 | .container {
179 | margin: util.$margin;
180 | }
181 | ```
182 |
183 | Caso não queria usar o namespace, esteja em processo de migração ou deseja utilizar outro nome porque o atual é grande, basta utilizar as e colocar um alias.
184 |
185 | ```scss
186 | @use "_util" as u; // o prefixo agora é `u`
187 | @use "_animations" as *; // não será necessário passar o namespace
188 | ```
189 |
190 | ## Arquitetura de projetos
191 |
192 | ### 7-1 Pattern
193 |
194 | *"One file to RULE them all.
195 |
196 | One file to FIND them.
197 |
198 | One file to BRING them all.
199 |
200 | And in the sass way MERGE them".*
201 |
202 | [Esse é o pattern mais utilizado](https://sass-guidelin.es/pt/#o-padro-7-1) para desfrutar do scss modules, ou seja, o scss modules é um modo de modularizar, cada arquivo é um componente, e cada componente é um modulo. A sua estrutura é a seguinte:
203 | abstracts, vendors, base, layout, components, pages e themes
204 |
205 | Existem vários patterns 4-1, 5-1 etc. Tudo vai depender da sua necessidade.
206 |
207 | ```zsh
208 | styles/
209 | |
210 | |– base/
211 | | |– _reset.scss # Reset/normalize
212 | | |– _color.scss # Paleta de cores da aplicação
213 | | |– _typography.scss # Typography rules
214 | | |– _index.scss # File used to import all base
215 | |
216 | |– layout/
217 | | |– _navigation.scss # Navigation
218 | | |– _grid.scss # Grid system
219 | | |– _header.scss # Header
220 | | |– _footer.scss # Footer
221 | | |– _sidebar.scss # Sidebar
222 | | |– _forms.scss # Forms
223 | |
224 | |– pages/ # Base views -> HOME, ABOUT, CONTACT etc.
225 | | |– _home.scss # Home specific styles
226 | | |– _contact.scss # Contact specific styles
227 | |
228 | |– themes/
229 | | |– _theme.scss # Default theme
230 | |
231 | |– abstract/
232 | | |– _variables.scss # Sass Variables
233 | | |– _functions.scss # Sass Functions
234 | | |– _mixins.scss # Sass Mixins
235 | | |– _index.scss # File used to import all abstracts
236 | |
237 | `– _index.scss # Main Sass file
238 | ```
239 |
240 | ## Próximos passos
241 |
242 | Sua jornada não termina aqui, agora é hora de você praticar e se aprofundar mais no assunto.
243 |
244 | > Recomendações de leitura:
245 |
246 | - [Sass Guidelines](https://sass-guidelin.es/pt/) by *community*
247 | - [SCSS como você nunca viu](https://dev.to/deverebor/scss-como-voce-nunca-viu-1d99) by *@deverebor*
248 | - [Sass Basics](https://sass-lang.com/guide) by *Sass*
249 |
250 | ---
251 |
252 | [Próxima Seção](./14-Considerações.md)
253 |
--------------------------------------------------------------------------------
/docs/tutorial/2-Conceitos/14-Considerações.md:
--------------------------------------------------------------------------------
1 | # Considerações finais
2 |
3 | Obrigado mesmo por ter chegado até aqui! Com o conhecimento que passamos, ja é possível fazer muita coisa mesmo com o Vue, durante as próximas seções iremos explorar todo o ecossistema que o **Vue** nos forneçe!
4 |
5 | A partir de agora, começaremos um projeto aplicando bibliotecas do **Vue**, assim conseguindo explicar coisas na prática, além de exercitar os conceitos.
6 |
7 | Qualquer dúvida ou reportar algum problema sobre o curso, reporte diretamente no [repositório](https://github.com/Novout/vue4noobs). E se possível deixe uma estrela, foi realmente trabalhoso.
8 |
9 | ## Tópicos Adicionais
10 |
11 | Tópicos como **componentes assíncronos** e **manipulações de carregamento** não serão abordados pois o objetivo do curso é uma introdução ao vue mostrando todo o seu **ecossistema**, mas iremos deixar a seguir se desejar ler sobre estes tópicos:
12 | *
13 | [Componentes Assíncronos](https://vueschool.io/articles/vuejs-tutorials/async-vuejs-components/)
14 |
15 | [Manipulações de Carregamento](https://alligator.io/vuejs/vue-async-components-load-error/)
16 |
17 | * Infelizmente a maioria dos conteúdos de **Vue** ainda estão em inglês, e é exatamente o motivo para a existência deste mini-curso sendo o objetivo conseguir atingir novos entusiastas em **Vue**, então em um futuro poderemos ter tópicos mais específicos traduzidos(por exemplo, o novo Vue 3).
18 |
19 | [Próxima Seção](./../3-Vuetify/1-Iniciando%20com%20Vuetify.md)
--------------------------------------------------------------------------------
/docs/tutorial/2-Conceitos/2-Diretivas.md:
--------------------------------------------------------------------------------
1 | # Diretivas
2 |
3 | Todas as **diretivas** do vue possuem o **v-**, como por exemplo os já ensinados **v-bind** e **v-on**, e nesta seção iremos introduzar novas diretivas para ajudar o seu desenvolvimento.
4 |
5 | ## V-IF
6 |
7 | Ele possui um funcionamento bem simples: analiza a condição imposta ou variavel e em caso de **true** exibe no template, e em caso de **false** ele não exibe.
8 |
9 | Exemplo:
10 |
11 | ```html
12 |
13 |
14 |
1
15 |
2
16 |
3
17 |
18 |
19 |
20 |
29 | ```
30 |
31 | Neste caso o **v-if** está atribuindo ao estado **mostrar** a sua condição, e por **mostrar** ser um booleano verdade ele será exibido ao template, mas:
32 |
33 | ```html
34 |
35 |
36 |
1
37 |
2
38 |
3
39 |
40 |
41 |
42 |
51 | ```
52 |
53 | Nessa situação, todo o **section**, **INCLUINDO** os conteúdos filhos **NÃO** serão exibidos no DOM
54 |
55 | Por exemplo:
56 |
57 | ```html
58 |
59 |
60 |
1
61 |
2
62 |
3
63 |
64 |
65 |
66 |
75 | ```
76 |
77 | Apenas um item(p) está sendo atribuido a condição, então em caso de mudanças no estado de **mostrar** apenas **p** sofrerá mutação.
78 |
79 | ---
80 |
81 | Podemos encadear condições, parecido com a sintaxe de algumas linguagens como **C** e ao próprio **JavaScript**
82 |
83 | ```html
84 |
85 |
86 |
1
87 |
2
88 |
3
89 |
90 |
91 |
92 |
101 | ```
102 |
103 | Também temos o **v-else-if**, mas iremos mudar um pouco a estrutura do código para ter sentido:
104 |
105 | ```html
106 |
107 |
108 |
Carlos
109 |
João
110 |
José
111 |
112 |
113 |
114 |
123 | ```
124 |
125 | ---
126 |
127 | ## V-FOR
128 |
129 | O **v-for** não é nada mais nada menos que um **forEach**,ou seja, ele percorre um array inteiro que é atrelado podendo assim exibir os conteúdo no template.
130 |
131 | Vamos mostrar um exemplo simples explicando os detalhes:
132 |
133 | ```html
134 |
135 |
136 |
137 |
162 |
163 | * o que o **v-for** está fazendo é pegar a **lista**, definindo cada parte da lista como **item** e percorrendo ele do começo ao fim, com isso podemos exibir itens específicos dos Objects da nossa lista, no caso **item.nome**.
164 |
165 | * para conseguir utilizar o **v-for**, precisamos passar uma **chave** usando a diretiva **v-bind**, no caso estamos passando o **id** como chave em **:key="item.id"**.
166 |
167 | Podemos capturar o segundo argumento, assim passando como **key** diretamente:
168 |
169 | ```html
170 |
171 |
172 |
173 |
Nome do Usuário: {{ item.nome }}
174 |
175 |
176 |
177 | ```
178 |
179 | o **v-for** não altera a maioria das diretivas, podendo usar normalmente, por exemplo:
180 |
181 | ```html
182 |
183 |
184 |
185 |
Par
186 |
Ímpar
187 |
188 |
189 |
190 | ```
191 |
192 | ---
193 |
194 | ## V-MODEL
195 |
196 | O **v-model** é usado para setar mudanças em uma variavel de **input**, por exemplo:
197 |
198 | ```html
199 |
200 |
201 |
202 |
{{ input }}
203 |
204 |
205 |
206 |
215 | ```
216 |
217 | Desta forma podemos atrelar diretamente uma variável que receberá o valor de uma entrada de dados, podendo assim manipular essa variável de forma flexiva.
218 |
219 | * O funcionamento do **v-model** em **propriedades** tem a necessidade de emitir o evento de alteração de volta para o componente pai por meio do **$emit** do vue, se quiser saber como fazer, clique [aqui](https://blog.oddeven.ch/blog/how-to-make-reusable-form-input-element-in-vue-js-2-6-and-vue-js-3-0/).
220 |
221 | * O **v-model** tem um funcionamento próprio para cada **type**, então recomendamos fortemente que olhe a [documentação](https://br.vuejs.org/v2/guide/forms.html) sobre o **v-model**.
222 |
223 | Na próxima seção, iremos falar sobre **computed properties** e **watchers**, mostrando como podem ser úteis durante o seu desenvolvimento, te esperamos lá! :)
224 |
225 | [Próxima Seção](./3-Computed%20e%20Watch.md)
226 |
--------------------------------------------------------------------------------
/docs/tutorial/2-Conceitos/3-Computed e Watch.md:
--------------------------------------------------------------------------------
1 | # Computed
2 |
3 | As **expressões** no template são muito convenientes, mas são destinadas a operações simples. Colocar muita lógica em seus modelos pode torná-los inchados e difíceis de manter. Por exemplo:
4 |
5 | ```html
6 |
7 | {{ message.toLowerCase().split('').reverse().join('') }}
8 |
9 | ```
10 |
11 | Neste ponto, o modelo **não** é mais simples e declarativo. Você precisa examiná-lo por um segundo antes de perceber que ele exibe a mensagem ao contrário. O problema é agravado quando você deseja incluir a mensagem invertida em seu modelo mais de uma vez.
12 |
13 | É por isso que, para qualquer lógica complexa, você deve usar uma **propriedade computada**(computed properties):
14 |
15 | ```js
16 |
17 |
18 |
Mensagem inicial: "{{ hello }}"
19 |
Mensagem computada: "{{ helloInvertido }}"
20 |
21 |
22 |
23 |
24 |
38 | ```
39 |
40 | O **Vue** está ciente de que **vm.helloInvertido** depende de **vm.hello**, portanto, ele atualizará todas as ligações que dependem de **vm.helloInvertido** quando o **vm.hello** for alterado. E a melhor parte é que criamos esse relacionamento de dependência declarativamente: a função getter acaba não tem efeitos colaterais, o que facilita a compreensão.
41 |
42 | ---
43 |
44 | ## Computed x Methods
45 |
46 |
47 | Em vez de uma propriedade computada, podemos definir a mesma função no formato de um **method**. Para o resultado final, as duas abordagens são exatamente iguais. No entanto, a diferença é que as propriedades calculadas são armazenadas em cache com base em suas dependências reativas. Uma propriedade computada somente reavaliará quando algumas de suas dependências reativas forem alteradas.
48 |
49 | Isso significa que, enquanto a mensagem não tiver sido alterada, o acesso múltiplo à propriedade computada reversedMessage retornará imediatamente o resultado calculado anteriormente sem precisar executar a função novamente.
50 |
51 | ```html
52 |
53 |
54 |
55 |
56 |
57 |
71 | ```
72 |
73 | Também podemos usar **methods** dentro de **computeds** normalmente:
74 |
75 | ```html
76 |
77 |
78 |
82 | {{ validacao }}
83 |
84 |
85 |
86 |
87 |
109 | ```
110 |
111 | ---
112 |
113 | Podemos usar as **computeds** em conjunto com o **v-bind**, além de outras **diretivas**:
114 |
115 | ```html
116 |
117 |
118 |
119 |
120 |
121 |
172 | ```
173 |
174 | * Os **Watchers** são recomendados para usar quando a necessidade de utilizar código **assíncrono** e quando não há necessidade de **retorno**.
175 |
176 | Na próxima seção iremos abordar o funcionamento do **CSS** no **Vue**, te vemos lá!
177 |
178 | [Próxima Seção](./4-CSS.md)
--------------------------------------------------------------------------------
/docs/tutorial/2-Conceitos/4-CSS.md:
--------------------------------------------------------------------------------
1 | ## CSS
2 |
3 | O **CSS** no **Vue** não se diferencia muito do **CSS** utilizado normalmente, apenas com algumas modificações.
4 |
5 | ## Scoped
6 |
7 | Quando uma tag `
18 |
19 |
20 |
21 |
He4rt Developers
22 |
23 |
24 | ```
25 |
26 | Dessa forma, irá ser feito um "hash" do componente para o **DOM final** (ou seja, depois de ser transformado pelo **Virtual DOM**).
27 |
28 | Exemplo:
29 |
30 | ```css
31 | .container[data-v-f84hf]
32 | ```
33 |
34 | * Você consegue observar isso facilmente olhando o html final no console de desenvolvedor.
35 |
36 | ## Module
37 |
38 | Módulos CSS é um sistema para modularização e composição de CSS no **Vue**. O **vue-loader** fornece integração de alto nível com módulos CSS como uma alternativa para parecida com a de escopos **CSS**.
39 |
40 | ```html
41 |
49 |
50 |
51 |
52 |
He4rt Developers
53 |
54 |
55 | ```
56 |
57 | Por conta da propriedade ser computada, é possível utilizar usando o **v-bind**
58 |
59 | ```html
60 |
63 | ```
64 |
65 | ## Estilos anexados
66 |
67 | Existe outras formas de utilziar o **v-bind** para anexar nossos estilos:
68 |
69 | Objeto:
70 |
71 | ```html
72 |
73 |
74 |
75 |
76 |
85 | ```
86 |
87 | Array(mostrado anteriormente em **module**):
88 |
89 | ```html
90 |
91 | ```
92 |
93 | Valores múltiplos(Vue v2.3.0+):
94 |
95 | ```html
96 |
97 | ```
98 |
99 | [Próxima Seção](./5-Instância%20Vue.md)
--------------------------------------------------------------------------------
/docs/tutorial/2-Conceitos/5-Instância Vue.md:
--------------------------------------------------------------------------------
1 | # Instância Vue
2 |
3 | Já vimos um pouco sobre a instância **new Vue**, agora vamos aprofundar mostrando os diversos recursos que o **Vue** disponibiliza para sua manipulação.
4 |
5 | ## Vue.component
6 |
7 | Podemos definir componentes diretamente na instância utilizando o **.component**:
8 |
9 | ```js
10 | Vue.component('card', {
11 | props: ['titulo'],
12 | template: '
{{ titulo }}
',
13 | })
14 | ```
15 |
16 | * O template anexa uma string ao template do componente, **NÃO** recomendamos utilizar na maioria das situações devido a **mutações** de estado.
17 |
18 | * Dessa forma, podemos acessar este componente de qualquer aqui **.vue** de nossa aplicação.
19 |
20 | ## Vue.use
21 |
22 | Para a utilização de plugins, utilizamos o **.use** antes ta **instanciação** do **Vue**. Vamos usar o exemplo de instalação do plugin [Vuelidate](https://vuelidate.js.org).
23 |
24 | ```js
25 | import Vue from 'vue';
26 | import Vuelidate from 'vuelidate';
27 | Vue.use(Vuelidate);
28 |
29 | //...
30 |
31 | new Vue({
32 | ...
33 | });
34 | ```
35 |
36 | ## Vue.prototype
37 |
38 | Com o **Vue** podemos criar variaveis globais para a manipulação de forma facilitada, com a convensão **$**.
39 |
40 | ```js
41 | import Vue from 'vue';
42 | import axios from 'axios';
43 |
44 | Vue.http = Vue.prototype.$http = axios;
45 |
46 | //...
47 |
48 | new Vue({
49 | ...
50 | });
51 | ```
52 |
53 | * Dessa forma conseguimos utilizar **bibliotecas** de forma **padronizada**.
54 |
55 | ## Vue.config
56 |
57 | Para conseguirmos alterar configurações padrões no **Vue**, utilizamos o **.config** para conseguir acessar estas configurações
58 |
59 | ```js
60 | Vue.config.productionTip = false;
61 |
62 | //...
63 |
64 | new Vue({
65 | ...
66 | });
67 | ```
68 |
69 | Na próxima seção iremos explicar o funcionamento dos **LifeCycleHooks**, te vemos lá!
70 |
71 | [Próxima Seção](./6-LifeCycleHooks.md)
72 |
--------------------------------------------------------------------------------
/docs/tutorial/2-Conceitos/6-LifeCycleHooks.md:
--------------------------------------------------------------------------------
1 | # LifeCycleHooks
2 |
3 | Os **LifeCycleHooks** são uma parte importante para todos os componentes do **Vue**. Você geralmente precisa saber quando seu componente é criado, adicionado ao DOM, atualizado ou destruído. Os ganchos do ciclo de vida são uma janela de como a biblioteca que você está usando funciona nos bastidores e, como tal, tendem a invocar sentimentos de ansiedade ou inquietação para os recém-chegados.
4 |
5 |
6 |
7 |
8 |
9 | Na próxima seção iremos explicar o funcionamento de um **BusEvent**, te vemos lá!
10 |
11 | ## Inicialização
12 |
13 | Ganchos(hooks) de criação são os primeiros ganchos que são executados em seu componente. Eles permitem que você execute ações antes mesmo de o seu componente ser adicionado ao **DOM**. Diferentemente de qualquer outro gancho, os ganchos de criação também são executados durante a renderização no servidor.
14 |
15 | Use ganchos de criação se precisar configurar coisas em seu componente durante a renderização do cliente e a renderização do servidor.Por exemplo, não faça requisição no localStorage, você não terá acesso ao DOM ou ao elemento de montagem de destino (a instância do **Vue**) dentro dos ganchos de criação.
16 |
17 | ```html
18 |
25 | ```
26 |
27 | * Os **hooks** tem o funcionamento parecido com um **método**.
28 |
29 | ## Created
30 |
31 | No hook criado, agora temos acesso aos dados reativos e os eventos. Os modelos e o DOM virtual **ainda** não foram montados ou renderizados.
32 |
33 | ```js
34 |
47 | ```
48 |
49 | ## Mount
50 |
51 | Hooks de montagem são geralmente os ganchos mais usados(não necessariamente da forma correta). Eles permitem que você acesse seu componente imediatamente antes e após a primeira renderização. No entanto, eles não são executados durante a renderização no servidor.
52 |
53 | O Mount é util quando precisa acessar ou modificar o **DOM** do seu componente **imediatamente** antes ou depois da renderização inicial.
54 |
55 | POR FAVOR(Sério mesmo): Se você precisa buscar alguns dados para o seu componente na inicialização utilize o **created** para isso, especialmente se você precisar desses dados durante a renderização no servidor(por exemplo, exibir dados em um dashboard).
56 |
57 | A diferença do **beforeMount** e **mounted** é que temos acesso total ao elemento nativo(new Vue()), sendo **mounted** o hook mais utilizado, geralmente usado para motificar o **DOM**.
58 |
59 | ```js
60 |
70 | ```
71 |
72 | ## Re-render com UpdateHook
73 |
74 | Os ganchos de atualização são chamados sempre que uma propriedade **reativa** usada por seu componente é **alterada**, ou qualquer outra coisa faz com que seja renderizada novamente. Dessa forma conseguimos trabalhar ao ciclo de **computer-render** do seu componente.
75 |
76 | ```js
77 |
96 | ```
97 |
98 | ## Destroy
99 |
100 | Quando você alcança o gancho destruído, vai restar pouca coisa em seu componente. Tudo o que foi anexado a ela já foi destruído, mas você pode usar o gancho destruído para fazer alguma limpeza necessária.
101 |
102 | ```js
103 |
110 | ```
111 |
112 | ## Outros Hook's
113 |
114 | Existem outros dois ganchos: **activated** e **deactivated**. Estes são para componentes keep-alive, que será abordado futuramente em nosso paper.
115 |
116 | Na próxima seção iremos abordar sobre o **BusEvent**, uma forma para conseguirmos transitar dados de componentes filhos mantendo a persistência dos dados, nos vemos lá!
117 |
118 | [Próxima Seção](./7-BusEvent.md)
119 |
--------------------------------------------------------------------------------
/docs/tutorial/2-Conceitos/7-BusEvent.md:
--------------------------------------------------------------------------------
1 | # BusEvent
2 |
3 | Dependendo da situação exige a necessidade de uma solução rápida e fácil para transmitir dados entre os componentes do **Vue**.
4 |
5 | Existe o [Vuex](https://vuex.vuejs.org/) para gerenciamento centralizado do estado. Assim, pode fornecer ao aplicativo uma única fonte de verdade.
6 |
7 | Mas para um aplicativo com arquitetura simples, basta comunicar-se entre componentes usando eventos. Para isso, podemos criar uma solução rápida e implementar o **EventBus**. Ele nos permite emitir um evento em um componente filho para outro componente filho(ambos possuindo o mesmo pai).
8 |
9 | Primeiro de tudo, precisamos de um mecanismo para transferir eventos entre componentes. Devido à simplicidade do **Vue**, ele nos permite criar uma nova **instância** com facilidade:
10 |
11 | ```js
12 | // ./src/event-bus.js
13 | import Vue from 'vue';
14 |
15 | const EventBus = new Vue();
16 |
17 | export default EventBus;
18 | ```
19 |
20 | Aqui temos um componente que importa o Vue e o EventBus. Quando o método **emitirEvento** do componente é chamado, ele emite um novo evento chamado **FORMULARIO** e passa uma carga útil junto com ele.
21 |
22 | ```js
23 | // primeiro-componente.js
24 | import Vue from 'vue';
25 | import EventBus from './event-bus';
26 |
27 | Vue.component('primeiro-componente', {
28 | ...
29 | methods: {
30 | emitirEvento() {
31 | EventBus.$emit('FORMULARIO', {
32 | nome: 'João',
33 | email: 'joao@hotmail.com'
34 | });
35 | }
36 | }
37 | });
38 | ```
39 |
40 | * O exemplo acima funcionaria normalmente em um **.vue**.
41 |
42 | Em outro componente, podemos registrar um ouvinte que escuta o evento **FORMULARIO** a ser transportado usando o EventBus. Assim que o evento aparecer, podemos executar o JavaScript com o payLoad recebido como argumento.
43 |
44 | ```js
45 | // segundo-componente.js
46 | import Vue from 'vue';
47 | import EventBus from './event-bus';
48 | Vue.component('segundo-componente', {
49 | ...
50 | mounted () {
51 | EventBus.$on('FORMULARIO', payload => {
52 | console.log(payload.nome, payload.email);
53 | });
54 | }
55 | });
56 | ```
57 |
58 | E pronto! Dessa forma conseguimos comunicar dois componentes filhos se a necessidade de **anexar** o fluxo de ambos os componentes.
59 |
60 | Para anexar os componentes:
61 |
62 | ```js
63 |
74 | ```
75 |
76 | Na próxima seção iremos de apresentar as transições, te vemos lá!
77 |
78 | [Próxima Seção](./8-Transições.md)
79 |
80 |
--------------------------------------------------------------------------------
/docs/tutorial/2-Conceitos/8-Transições.md:
--------------------------------------------------------------------------------
1 | # Transições
2 |
3 | As transições não servem apenas para adicionar um toque bonito ao seu aplicativo(juro). Uma boa transição pode ser a diferença entre um usuário se inscrever, fazer uma compra ou sair completamente do site.
4 |
5 | O Vue.js oferece várias maneiras de animar seu aplicativo, incluindo transições e animações CSS, e usando JavaScript para manipular o DOM durante ganchos de transição. Você pode até conectar-se a bibliotecas de terceiros, como [GSAP](https://greensock.com/gsap/) ou [VelocityJS](http://velocityjs.org/).
6 |
7 | Uma transição ocorre quando um elemento passa de A para B. Eles estão entre dois estágios: do **estado inicial** (A) ao **estado final** (B). Eles funcionam muito bem para coisas como passar o mouse sobre links e botões ou adicionar um novo item a uma lista. O principal objetivo das transições é criar uma demonstração natural de que algo mudou. Um bom **exemplo** de uma transição no mundo real seria **portas automáticas**. Eles **começam fechados** e quando você pisa na frente deles, eles **passam** automaticamente para o estado **aberto**.
8 |
9 | ## Elementos de Transição
10 |
11 | O **Vue** possui o elemento `` que facilita o manuseio de animações JavaScript, animações CSS e demais transições em seus elementos ou componentes.
12 | No caso de transições CSS, o elemento `` cuida da aplicação e da não aplicação de classes. Tudo o que você precisa fazer é definir a aparência do elemento durante a transição.
13 | Ele age como qualquer outro componente do Vue.js e você pode usar as mesmas diretivas como **v-if e **v-show**.
14 |
15 | Para isso, o **Vue** usa **classes de transição** padrões para facilitar(talvez nem tanto) o manuseio de todo o estado da transição.
16 |
17 | * Exemplo de uma transição simples que envolve a opacidade do elemento:
18 |
19 |
20 |
21 |
22 |
23 | O *-active é na onde definimos o **tempo de transição** da nossa transição, e nas pontas o **estado** que irá ocorrer no começo ou no fim.
24 |
25 | ## Transições CSS
26 |
27 | Iremos agora mostrar um exemplo na prática usando as **transições**:
28 |
29 | ```js
30 |
31 |
32 |
33 |
34 |
Oiiiiiiiiiiiiiiiiiiiii
35 |
36 |
37 |
38 |
39 |
48 |
49 |
59 | ```
60 |
61 | * Podemos criar nossos próprios nomes para as transições, no caso atribuimos o name="opacity", assim o **vue-loader** irá pesquisar a tag `opacity-**` para carregar as classes na transição.
62 |
63 | * Como no nosso exemplo tanto a entrada quanto a saida possuem a mesma lógica, podemos economizar código juntando em um mesmo escopo.
64 |
65 | * Nesse caso, omitimos o estado inicial do componente, pois se não colocarmos o **Vue** considera o estado inicial dos atributos, no caso por padrão temos a opacidade em 1.
66 |
67 | ## Animações
68 |
69 | Assim como as transições, podemos usar **animações** de uma forma parecido em nossos componentes **transition**:
70 |
71 | ```js
72 |
73 |
74 |
75 |
76 |
Oiiiiiiiiiiiiiiiiiiiii
77 |
78 |
79 |
80 |
81 |
90 |
91 |
109 | ```
110 |
111 | ## Out-in
112 |
113 | Utilizando o **Out-in**, podemos **esperar** a transição de um componente, assim evitando **mutações** inesperadas(na verdade, esperadas) no template:
114 |
115 | ```js
116 |
117 | ...
118 |
119 | ```
120 |
121 | ## Transições entre componentes
122 |
123 | ```js
124 |
125 |
126 |
127 | ```
128 |
129 | * O **component** irá buscar o nome **componente** nos componentes que estão registrados na instância.
130 |
131 | ## Transição em grupos
132 |
133 | Quando temos mais de um elemento dentro de um **transition**(no caso mais que 1 elemento filho na transição), temos que usar o **transition-group**:
134 |
135 | ```js
136 |
137 |
138 | {{ item }}
139 |
140 |
141 | ```
142 |
143 | * No caso **item** irá assumir a tag **p** passada no **transition-group**.
144 |
145 | ## Move
146 |
147 | Usando o **move** é aplicado diretamente um evento de transição a uma lista que possui elementos sendo alterados.
148 | ```css
149 | .classe-move {
150 | transition: transform 1s;
151 | }
152 | ```
153 |
154 | ## Transições em methods
155 |
156 | Podemos anexar transições em nosso template:
157 |
158 | ```js
159 | @before-enter="beforeEnter"
160 | // ou
161 | v-on:before-enter="beforeEnter"
162 | methods: {
163 | beforeEnter(el) {
164 | el.style.opacity = 0
165 | el.style.height = 0
166 | }
167 | }
168 | ```
169 |
170 | Te esperamos na próxima seção, falaremos sobre o **Keep Alive** e como ele pode ser útil, nos vemos lá!
171 |
172 | [Próxima Seção](./9-Keep%20Alive.md)
--------------------------------------------------------------------------------
/docs/tutorial/2-Conceitos/9-Keep Alive.md:
--------------------------------------------------------------------------------
1 | # Keep Active
2 |
3 | Ao alternar entre esses componentes, às vezes, precisamos manter o estado deles ou evitar a nova renderização por motivos de desempenho. Por exemplo, ao expandir um pouco a nossa interface com guias.
4 |
5 | Por padrão, se alterarmos de um componente para outro, o componente será destruido e terá que ser criado novamente.
6 |
7 | A recriação de componentes dinâmicos normalmente é um comportamento útil, mas se precisássemos que as instâncias de componentes fossem armazenadas em cache depois que elas fossem criadas pela primeira vez. Para resolver esse problema, podemos agrupar nosso componente dinâmico com um elemento ``:
8 |
9 | ```html
10 |
11 |
12 |
13 | ```
14 |
15 | * Observe que o **keep-alive** exige que os componentes alternados tenham nomes globais.
16 |
17 | ## Máximo de renderizações
18 |
19 | Podemos delimitar o numero máximo de componentes que terão sua instância salva, descartando os componentes seguindo o padrão de uma [Fila](https://www.cos.ufrj.br/~rfarias/cos121/filas.html).
20 |
21 | ```html
22 |
23 |
24 |
25 | ```
26 |
27 | ## Limitações aos componentes
28 |
29 | Conseguimos delimitar quais componentes terão suas instâncias salvas utilizando o **include**:
30 |
31 | ```html
32 |
33 |
34 |
35 | ```
36 |
37 | Na próximo seção iremos abordar sobre **mixins** no **Vue**, te esperamos lá!
38 |
39 | [Próxima Seção](./10-Mixins.md)
40 |
--------------------------------------------------------------------------------
/docs/tutorial/3-Vuetify/1-Iniciando com Vuetify.md:
--------------------------------------------------------------------------------
1 | # O que e Vuetify
2 |
3 | [Vuetify](https://vuetifyjs.com/pt-BR/) é uma Biblioteca Vue UI com Material Components para a sua aplicação, tirando a necessidade de conhecimentos sobre UI.
4 |
5 | ## Instalação
6 |
7 | Lembra do começo do nosso curso que usamos o **Vue-CLI** para criar nosso projeto? Iremos utilizar novamente ele!
8 |
9 | Estando em um diretório para criar o projeto, execute o comando `vue ui` para iniciar a UI. Na outra vez fizemos por comando, agora quero te mostrar como fazer isso diretamente da UI.
10 |
11 | * Para adicionar uma biblioteca em um projeto existente, podemos usar o add: `vue add vuetify`
12 |
13 | Irá aparecer esta tela:
14 |
15 |
16 |
17 |
18 |
19 | Crie o projeto com o nome de sua **preferência** e clique em **Next**.
20 |
21 | Na próxima tela selecione a opção **Manual** e de **Next**.
22 |
23 |
24 |
25 |
26 |
27 | Vamos deixar selecionado o **Babel** e o **Linter** no momento e de **Next**.
28 |
29 | * No nosso tutorial, foi usado o preset do airbnb `@vue/eslint-config-airbnb`
30 |
31 | Na próxima tela, escolha as suas preferências de linter, e depois de **Next**.
32 |
33 | Após avançar, você terá a opção de **salvar seu preset**:
34 |
35 |
36 |
37 |
38 |
39 | Depois se salvar(ou não) seu preset, o vue começará a carregar as depedências (aka yarn install / npm run install).
40 |
41 |
42 |
43 |
44 |
45 | Após isso, teremos o **dashboard** principal do ui:
46 |
47 |
48 |
49 |
50 |
51 | ## Adicionando Vuetify
52 |
53 | Para conseguirmos adicionar o **Vuetify**, iremos em **Plugin**, e no canto superior direito em **Add Plugin**
54 |
55 |
56 |
57 |
58 |
59 | Procuramos por **Vuetify**, clicamos e depois em `Install vue-cli-plugin-vuetify`
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | Escolha a opção padrão e espere instalar.
70 |
71 | Agora podemos executar o comando **yarn serve** em nosso projeto, e acesse o localhost que será exibido:
72 |
73 |
74 |
75 |
76 |
77 | ## Estrutura
78 |
79 | Vamos dar uma olhada no `./src/App.vue`. De início parece ser algo muito complicado mas entendendo o que cada componente está fazendo irá facilitar a compreensão:
80 |
81 | O nosso componente está envolvido com o container *v-app* e possui dois filhos:
82 |
83 | **v-app-bar** que é o nosso header que está na aplicação.
84 |
85 | **v-container** que está carregando o componente **HelloWorld**, que está centralizado no meio de nossa aplicação.
86 |
87 | ## Header
88 |
89 | Vamos pegar só o header para analizar:
90 |
91 | ```html
92 |
97 |
98 |
106 |
107 |
115 |
116 |
117 |
118 |
119 |
124 | Latest Release
125 | mdi-open-in-new
126 |
127 |
128 | ```
129 |
130 | Temos a **div** que junta tanto o **icon** quanto o nome do **Vuetify**, dessa forma estando ao lado **esquerdo** do header**.
131 |
132 | o **v-spacer** separa a nossa **div** e o **v-btn**, mantendo cada um de um lado diferente.
133 |
134 | o **v-btn** leva a página de últimos lançamentos do **Vuetify**, tendo em seu conteúdo o ícone e a descrição do **v-btn**.
135 |
136 | ## HelloWorld
137 |
138 | Não temos nada muito diferente do que já estamos acostumados, o funcionamento dos **v-row** e **v-col** é muito parecido com o display **grid** de nosso querido CSS, iremos também abordar sobre este sistema do **Vuetify** na próxima seção.
139 |
140 | * Recomendamos **>MUITO<** que explore a [documentação](https://vuetifyjs.com/pt-BR/getting-started/quick-start/) do **Vuetify**, pois ele possui uma gama muito vasta que pode resolver um problema específico seu.Felizmente muito conteúdo da documentação do **Vuetify** possui tradução para PT-BR!
141 |
142 | Nas próximas seções do **Vuetify**, iremos ensinar a como extrair o conteúdo dessa framework UI.
143 |
144 | [Próxima Seção](./2-Criando%20Componentes.md)
145 |
--------------------------------------------------------------------------------
/docs/tutorial/3-Vuetify/2-Criando Componentes.md:
--------------------------------------------------------------------------------
1 | # Componentes
2 |
3 | Nesta seção iremos explorar todo a vasta gama de componentes que o **Vuetify** nos disponibiliza.
4 |
5 | ## Projeto
6 |
7 | A partir desse ponto de nosso curso, iremos utilizar o que iremos fazer para as outras seções, apenas implementando mais conteúdo, então faça o conteúdo que iremos passar e fique livre para implementar conteúdos adicionais :)
8 |
9 | Não iremos disponibilizar o projeto por cada seção, apenas o projeto final, pois o intuito é que você faça. "Ah mas eu tive um problema", perfeito! Revise seu código e procure entender o **porquê** passou despercebido e os motivos de não ter funcionado. Entregar o projeto final pronto só vai enfatizar seus erros, que, em um momento em que você **não pode errar**(ou que pelo menos não deveria) poderá te atrapalhar.Você pode contar com a ajudar da [He4rt](http://discord.io/He4rt) sempre que quiser!
10 |
11 | Iremos fazer uma simples landing page de começo, posteriormente uma aplicação com login e dashboard.
12 |
13 | Durante todo o processo iremos utilizar o **Vuetify**, mas se preferir utilizar outra framework de CSS de seu agrado, fica á vontade também :)
14 |
15 | ## Landing Page
16 |
17 | Vamos fazer a landing page baseado em: Header - Main
18 |
19 | Tanto o **Header** quanto o **Footer** serão componentes reutilizáveis, enquanto o **Main** fará parte da view.
20 |
21 | Dessa forma, conseguimos reaproveitar componentes e modularizar nosso projeto.
22 |
23 | Para começar, vamos excluir todo o conteúdo inicial do **Vuetify** que está no nosso projeto:
24 |
25 | * Excluir o componente HelloWorld.vue
26 | * Vamos trocar o conteúde do App.vue para:
27 |
28 | ```html
29 |
30 |
31 |
Hello He4rt
32 |
33 |
34 |
35 |
43 | ```
44 |
45 | ## Header
46 |
47 | Primeiramente, vamos fazer o Header.
48 |
49 | Crie uma pasta em `./src/components/header/Header.vue`
50 |
51 |
52 |
53 |
54 |
55 | E importe em seu componente App.vue:
56 |
57 | ```html
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
79 | ```
80 |
81 | Para começar, vamos utilizar o **v-app-bar**:
82 |
83 | ```html
84 |
85 |
90 |
91 |
92 | ```
93 |
94 | * Setamos a cor da nossa bar com o **color**, segundamente o **accent-4** acentua a coloração da bar
95 |
96 | * Dense retira os paddings default do **v-app-bar**
97 |
98 | * Dark quer dizer o tema que estamos usando, e esse tema por padrão deixa as letras com cor **branca**, iremos ter uma seção apenas para customizações, então não se preocupe.
99 |
100 | Agora iremos acrescentar conteúdos:
101 |
102 | ```html
103 |
104 |
109 |
110 |
111 | He4rt Developers
112 |
113 |
114 | ```
115 |
116 | * O **app-bar-nav-icon** é o ícone sanduiche por padrão.
117 |
118 | * Estamos criando um **título** com o **v-toolbar-title** com o nome da **He4rt**
119 |
120 | Vamos agora setar uma lista de botões e espaçar para a **direita**
121 |
122 | ```html
123 |
124 |
129 |
130 |
131 | He4rt Developers
132 |
133 |
134 |
135 |
139 |
140 |
141 | mdi-dots-vertical
142 |
143 |
144 |
145 | {}"
149 | >
150 | {{ titulo }}
151 |
152 |
153 |
154 |
155 |
156 |
157 |
169 | ```
170 |
171 | * O template irá indicar para a lista quando ela deve exibir o conteudo.
172 |
173 | * Usamos a desconstrução para passar dados no **v-for**.
174 |
175 | * O **@click** irá ativar o estilo do nosso botão.
176 |
177 | * Para ativar a lista também é possivel usando o **v-if**, mas vamo seguir usando o padrão do **Vuetify**.
178 |
179 | * O **href** iremos utilizar para redireciar usando **rotas** futuramente.
180 |
181 | Dessa forma, nosso **Header** ficará assim:
182 |
183 |
184 |
185 |
186 |
187 | ## Main
188 |
189 | O nosso **main** será bem simples, com a logo da He4rt, descrição e botões:
190 |
191 | ```html
192 |
193 |
194 |
227 |
228 |
229 | ```
230 |
231 | * O **Vuetify** possui um sistema de classes [proprias](https://vuetifyjs.com/pt-BR/styles/flex/) para usar, recomendo **MUITO** que veja para melhor aproveitamento.
232 |
233 | * Podemos usar o **:src** para procurar diretamente uma imagem em nossa aplicação, no caso em `./assets`.
234 |
235 | * O **Vue** possui um sistema de caminho relativo usando o **@**, tendo o **@** começando da pasta **/src**
236 |
237 | * Para baixar a imagem do Vue clique [aqui](https://en.wikipedia.org/wiki/Vue.js#/media/File:Vue.js_Logo_2.svg).
238 |
239 | * Também podemos formatar [textos](https://vuetifyjs.com/pt-BR/styles/text/) e espaçar [itens](https://vuetifyjs.com/pt-BR/styles/spacing/) com o **Vuetify**.
240 |
241 | * Fizemos uma forma simples de centralização, mas recomendamos que dê uma olhada no [grid](https://vuetifyjs.com/pt-BR/components/grids/).
242 |
243 | * Fizemos a landing com a temática do curso, mas fique a vontade para customizar a landing page da forma que te agradar mais :)
244 |
245 | * O **Main** poderia virar um componente também.
246 |
247 | A cara final da nossa landing page:
248 |
249 |
250 |
251 |
252 |
253 | Na próxima seção iremos mostrar em como customizar opção do **Vuetify**, assim colocando definições para todos os componentes, te vemos lá!
254 |
255 | [Próxima Seção](./3-Customização.md)
--------------------------------------------------------------------------------
/docs/tutorial/3-Vuetify/3-Customização.md:
--------------------------------------------------------------------------------
1 | # Customização
2 |
3 | Vamos agora customizar o nosso **tema**, para conseguirmos seguir uma padronização.
4 |
5 | Quando instalamos o **Vuetify**, foi criado uma pasta **plugins** contendo o **vuetify.js**:
6 |
7 | ```js
8 | import Vue from 'vue';
9 | import Vuetify from 'vuetify/lib';
10 |
11 | Vue.use(Vuetify);
12 |
13 | export default new Vuetify({
14 | });
15 | ```
16 |
17 | Dentro do **Vuetify** podemos passar configurações por padrão.
18 |
19 | Por exemplo, vamos passar o tema padrão para a aplicação:
20 |
21 | ```js
22 | import Vue from 'vue';
23 | import Vuetify from 'vuetify/lib';
24 |
25 | Vue.use(Vuetify);
26 |
27 | export default new Vuetify({
28 | theme: {
29 | dark: true,
30 | },
31 | });
32 | ```
33 |
34 | ## Cores
35 |
36 | Podemos também customizar diretamente as **cores**:
37 |
38 | ```js
39 | import Vue from 'vue';
40 | import Vuetify from 'vuetify/lib';
41 |
42 | Vue.use(Vuetify);
43 |
44 | export default new Vuetify({
45 | themes: {
46 | light: {
47 | primary: '#a142f5',
48 | secondary: '#f5f5f5',
49 | accent: '#c463e6',
50 | error: '#e66365',
51 | },
52 | },
53 | theme: {
54 | light: true,
55 | },
56 | });
57 | ```
58 |
59 | Dessa forma, podemos acessar as cores globais do **Vuetify** de uma forma já **definida**
60 |
61 | Na próxima seção iremos discutir um pouco sobre o que virá nas próximas seções, te vemos lá!
62 |
63 | [Próxima Seção](./4-Considerações.md)
--------------------------------------------------------------------------------
/docs/tutorial/3-Vuetify/4-Considerações.md:
--------------------------------------------------------------------------------
1 | # Considerações
2 |
3 | ## Projeto
4 |
5 | Todas as próximas seções de nosso curso será implementando conteúdo em nosso projeto:
6 |
7 | * VueRouter - Implementação das rotas e construção do formulário de login
8 |
9 | * Vuex - Gerenciamento de Estado nos permitindo a salvar dados do usuário para a aplicação
10 |
11 | * Bibliotecas Adicionais - Deixar a aplicação mais robusta e refinamentos gerais
12 |
13 | * Testes e Documentação - Relacionado ao projeto
14 |
15 | A Partir do **Nuxt** iremos mostrar outras tecnologias baseadas no **Vue**.
16 |
17 | ## Recomendações
18 |
19 | Explore os Componentes que o [Vuetify](https://vuetifyjs.com/pt-BR/components/cards/) dispoem, irão complementar e muito sua aplicação!
20 |
21 | ---
22 |
23 | Na próxima seção iremos iniciar com o **VueRouter** e já utilizando em nosso projetinho, nos vemos lá!
24 |
25 | [Próxima Seção](../4-Vue%20Router/1-Iniciando%20com%20Vue%20Router.md)
26 |
--------------------------------------------------------------------------------
/docs/tutorial/4-Vue Router/1-Iniciando com Vue Router.md:
--------------------------------------------------------------------------------
1 | # Iniciando com Vue Router
2 |
3 | **VueRouter** é o **router** oficial do **VueJS**, Por isso ele se integra profundamente ao núcleo do **Vue**. para facilitar a criação de aplicativos de página única com o **Vue**. Características incluem:
4 |
5 | * Rotas aninhadas
6 | * Configuração modular de roteador baseada em componente
7 | * Parâmetros de rota, consulta
8 | * Integração com efeitos de transição
9 | * Controle de navegação refinado
10 | * Links com classes CSS ativas automáticas
11 | * Modo de histórico HTML5 ou modo de hash, com fallback automático no IE9
12 | * Comportamento de rolagem personalizável
13 |
14 | ## Adicionando ao Projeto
15 |
16 | Primeiramente, iremos instalar a dependência do **vue-router**.
17 |
18 | `yarn add vue-router`
19 |
20 | Criamos um arquivo `vuerouter.js` em `./src/plugins/vuerouter.js'` e adicionamos o seguinte:
21 |
22 | `./src/plugins/vuerouter.js`
23 |
24 | ```js
25 | import Vue from 'vue';
26 | import VueRouter from 'vue-router';
27 | import routes from '@/routes.js';
28 |
29 | Vue.use(VueRouter);
30 |
31 | export default new VueRouter({
32 | mode: 'history',
33 | routes,
34 | });
35 | ```
36 |
37 | * Estamos exportando o **VueRouter**, contendo nossas rotas e no modo [history](https://router.vuejs.org/guide/essentials/history-mode.html#example-server-configurations).
38 |
39 | Agora vamos importar em nosso `main.js`.
40 |
41 | ```js
42 | // ...
43 | import router from '@/plugins/vuerouter.js';
44 | // ...
45 | const app = new Vue({
46 | router
47 | }).$mount('#app');
48 | ```
49 |
50 | Não acabamos ainda, vamos criar o arquivo `routes.js` na raiz do `src` que é a onde ficará a declaração de nossas rotas.
51 |
52 | `./src/routes.js`
53 |
54 | ```js
55 | import Home from './pages/Home.vue';
56 |
57 | export default [
58 | {
59 | path: '/',
60 | component: Home,
61 | },
62 | {
63 | path: '*',
64 | redirect: '/',
65 | },
66 | ];
67 | ```
68 |
69 | * Se ele não encontrar a rota '/', irá para a genérica '*', que no caso dá um redirect para o próprio '/', isso será util quando tivermos mais rotas no projeto.
70 |
71 | * Também seria possível criar um componente **Error.vue** por exemplo, e colocar no lugar do **redirect**.
72 |
73 | * Você pode utilizar RegEx no `path`.
74 |
75 | Vamos transferir o nosso conteúdo de `App.vue` para `./src/pages/Home.vue`.
76 |
77 | * Renomeie o import do **Header**:
78 |
79 | `./src/pages/Home.vue`
80 |
81 | ```js
82 | import Header from '../components/header/Header.vue';
83 | ```
84 |
85 | E o novo conteúdo de `./src/App.vue` será:
86 |
87 | ```js
88 |
89 |
90 |
91 |
92 |
95 | ```
96 |
97 | * O **router-view** é o que irá exibir a rota em que estamos, no caso '/' irá exibir a rota **Home** neste **router-view**.
98 |
99 | A estrutura final ficou a seguinte:
100 |
101 |
102 |
103 |
104 |
105 | Na próxima seção, iremos criar o nosso formulário de login, e a rota que ela irá redireciar, assim ensinando um pouco sobre **Navegação**, nos veremos lá!
106 |
107 | [Próxima Seção](./2-Navegação.md)
--------------------------------------------------------------------------------
/docs/tutorial/4-Vue Router/2-Navegação.md:
--------------------------------------------------------------------------------
1 | # Navegação
2 |
3 | Agora, vamos criar uma rota para `'/login`, assim criando nosso formuário:
4 |
5 | `./src/routes.js`
6 |
7 | ```js
8 | import Home from './pages/Home.vue';
9 | import Login from './pages/Login.vue';
10 |
11 | export default [
12 | {
13 | path: '/login',
14 | component: Login,
15 | },
16 | {
17 | path: '/',
18 | component: Home,
19 | },
20 | {
21 | path: '*',
22 | redirect: '/',
23 | },
24 | ];
25 | ```
26 |
27 | `./src/pages/Login.vue`
28 |
29 | ```html
30 |
31 |
44 |
45 | * As rotas **genéricas** sempre ficam na parte de baixo do array, pois a leitura é de cima para baixo.
46 |
47 | Agora vamos fazer nosso **container** do login:
48 |
49 | ```html
50 |
51 |
52 |
53 |
57 |
61 |
66 |
67 |
72 | Formulário de Login
73 |
74 |
75 |
76 |
81 |
86 |
87 |
88 |
89 | Não possui uma conta? Clique
90 |
91 |
94 | aqui
95 |
96 |
97 |
98 |
99 | Entrar
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
112 | ```
113 |
114 | * Como falamos até mesmo de forma redundante, leia a documentação do Vuetify, fará muita diferença!
115 |
116 | * Iremos utilizar o sistema de **grid** do **Vuetify** para centralizar nosso **container**
117 |
118 | Na descrição para **registrar**, implementamos com o **router-link** para redirecionar para a rota **/registrar**, como essa rota ainda não foi implementada ela irá redireciar para '/'.
119 |
120 | Vamos implementar o **v-model** para **escutar** os input's de dados em nosso formulário:
121 |
122 | `./src/pages/Login.vue`
123 |
124 | ```html
125 |
126 |
127 |
128 |
132 |
136 |
141 |
142 |
147 | Formulário de Login
148 |
149 |
150 |
151 |
157 |
163 |
164 |
165 |
166 | Não possui uma conta? Clique
167 |
168 |
171 | aqui
172 |
173 |
174 |
175 |
176 | Entrar
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
196 | ```
197 |
198 | * Estamos disponibilizando o código direto da estrutura visual para te mostrar novos recursos, por isso demos uma seção apenas para o Vuetify.
199 |
200 | Para submeter nosso formulário, iremos usar a diretiva **v-on** no **form**, pois futuramente iremos fazer a validação deste formulário em nosso projeto.
201 |
202 | `./src/pages/Login.vue`
203 |
204 | ```html
205 | Entrar
210 |
211 | ```
212 |
213 | ```html
214 |
237 | ```
238 |
239 | * Estamos mandando os dados para o localStorage e pegando eles posteriores (não é uma boa ideia mandar a senha para o localStorage sem hash, tá?).
240 |
241 | * Também podemos redirecionar rotas acessando o `this.$router`.
242 |
243 | Agora com a rota, já podemos implementar na nossa landing o redirecionamento para a rota:
244 |
245 | `./src/components/header/Header.vue`
246 |
247 | ```html
248 |
249 |
254 |
255 |
256 | He4rt Developers
257 |
258 |
259 |
260 |
264 |
265 |
266 | mdi-dots-vertical
267 |
268 |
269 |
270 |
271 |
276 | {{ titulo }}
277 |
278 |
279 |
280 |
281 |
282 |
283 |
300 | ```
301 |
302 | Na próxima seção iremos mostrar o funcionamento de rotas filhas, implementando inicialmente um protótipo de **dashboard**, te vemos lá!
303 |
304 | [Próxima Seção](./3-Rotas%20Filhas.md)
--------------------------------------------------------------------------------
/docs/tutorial/4-Vue Router/3-Rotas Filhas.md:
--------------------------------------------------------------------------------
1 | # Rotas Filhas
2 |
3 | Primeiramente, vamos criar a nossa rota `/dashboard` e sua rota **filha**:
4 |
5 | `./src/routes.js`
6 |
7 | ```js
8 | import Home from './pages/Home.vue';
9 | import Login from './pages/Login.vue';
10 | import Dashboard from './pages/Dashboard.vue';
11 |
12 | import DashboardHome from './components/dashboard/DashboardHome.vue';
13 |
14 | export default [
15 | {
16 | path: '/login',
17 | component: Login,
18 | },
19 | {
20 | path: '/dashboard',
21 | component: Dashboard,
22 | children: [
23 | { path: '/', component: DashboardHome },
24 | ],
25 | },
26 | {
27 | path: '/',
28 | component: Home,
29 | },
30 | {
31 | path: '*',
32 | redirect: '/',
33 | },
34 | ];
35 | ```
36 |
37 | * Dessa forma, iremos ter outro **router-view**, só que esse dentro da view **dashboard**, dessa forma podermos alterar o conteúdo do dashboard mantendo o nosso **drawer**
38 |
39 | * Como apenas estamos indo para `/dashboard`, o '/' é considerado a rota filha padrão do componente `Dashboard.vue`
40 |
41 | Agora em `./pages/Dashboard.vue`
42 |
43 | ```js
44 |
45 |
46 |
47 |
52 |
53 |
54 |
55 |
56 |
57 | Olá {{ conta }}!
58 | Drawer
59 |
60 |
61 |
62 |
63 |
64 |
70 |
71 | {{ item.icon }}
72 |
73 |
74 | {{ item.titulo }}
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
138 | ```
139 |
140 | Calma, respira fundo que iremos explicar o que está acontecendo:
141 |
142 | * O primeiro **v-col** indica o **drawer** de itens, esse que carrega os **items** que estão em nosso **data**.
143 |
144 | * Pela lista, estamos anexando nosso **href** para redirecionar para as rotas filhas.
145 |
146 | * Fizemos o mesmo método que usamos na landing para **redirecionar**, existe outras formas de mudar de rota como o **replace()**, e outras manipulações como o **back()**, mas focaremos apenas no **push()** para ficar simples.
147 |
148 | * Na outra coluna, estamos usando o **router-view** para exibir nossa rota **filha**.
149 |
150 | * no **mounted()** estamos buscando o nosso objeto no localStorage e exibindo na aplicação no **drawer**
151 |
152 | ## Rota Filha
153 |
154 | No caso, a rota filha terá o seguinte conteúdo:
155 |
156 | `./src/components/dashboard/DashboardHome.vue`
157 |
158 | ```js
159 |
160 |
163 |
164 |
167 |
168 |
175 |
176 |
182 |
186 |
187 | {{ active ? 'mdi-heart' : 'mdi-heart-outline' }}
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
222 | ```
223 |
224 | * Estamos fazendo um ternário para exibir o ícone correto
225 |
226 | * Pegando o elemento da lista e **concatenando** para requisitar as **imagens**
227 |
228 | * o **@click="toogle"** está diretamente relacionado os v-model no **group-item**.
229 |
230 | E como resultado final, o nosso dashboard ficará assim:
231 |
232 |
233 |
234 |
235 |
236 | Na próxima seção iremos ensinar a como implementar um **Middleware**, nos vemos lá!
237 |
238 | [Próxima Seção](./4-Guardas%20de%20Rota.md)
--------------------------------------------------------------------------------
/docs/tutorial/4-Vue Router/4-Guardas de Rota.md:
--------------------------------------------------------------------------------
1 | # Guardas de Rota
2 |
3 | O guarda de rota irá verificar alguma condição quando alguem entrar ou sair da rota, assim podemos garantir a segurança destas.
4 |
5 | ## Guardas Globais
6 |
7 | Primeiramente, vamos setar uma nova chave no localStorage:
8 |
9 | `./src/pages/Login.vue`
10 |
11 | ```js
12 |
34 | ```
35 |
36 | Adicionando o **AUTENTICADO**, podemos usá-lo para verificação.
37 |
38 | Agora vamos utilizar o **beforeEnter** nas **rotas** para fazer uma verificação **ANTES** do usuário poder acessar a rota, ou seja, antes do **created()** ser executado.
39 |
40 | O **beforeRouter** e **afterRouter** possuem três parâmetros por padrão: to, from e next. to e from são as referência da rota de onde está vindo(from) e para onde está indo(to). o **next** é a condição se o redirecionamento da rota continuará ou não.
41 |
42 | `./src/routes.js`
43 |
44 | ```js
45 | import Home from './pages/Home.vue';
46 | import Login from './pages/Login.vue';
47 | import Dashboard from './pages/Dashboard.vue';
48 |
49 | import DashboardHome from './components/dashboard/DashboardHome.vue';
50 |
51 | export default [
52 | {
53 | path: '/dashboard',
54 | component: Dashboard,
55 | beforeEnter: (to, from, next) => {
56 | if (localStorage.getItem('AUTENTICADO')) {
57 | next();
58 | } else {
59 | next({
60 | path: '/',
61 | });
62 | }
63 | },
64 | children: [
65 | { path: '/', component: DashboardHome },
66 | ],
67 | },
68 | ];
69 | ```
70 |
71 | Dessa forma, se acessarmos sem estar com autenticado, iremos ser redireciados **ANTES** de entrar na rota, evitando problemas.
72 |
73 | * Essa é uma forma simples, o correto seria armazenar o booleano em um gerenciador de estado(Vuex) e verificar a entrada e saida de todas as rotas, vamos falar um pouco sobre quando chegarmos nas seções do Vuex.
74 |
75 | ## VueRouter Multiguard
76 |
77 | Também podemos criar grupos de autenticação:
78 |
79 | Adicionamos um novo package: `yarn add vue-router-multiguard`
80 |
81 | E aplicamos no router:
82 |
83 | ```js
84 | import multiguard from 'vue-router-multiguard';
85 |
86 | import Home from './pages/Home.vue';
87 | import Login from './pages/Login.vue';
88 | import Dashboard from './pages/Dashboard.vue';
89 |
90 | import DashboardHome from './components/dashboard/DashboardHome.vue';
91 |
92 | const logado = (to, from, next) => {
93 | if (localStorage.getItem('AUTENTICADO')) {
94 | next();
95 | } else {
96 | next({
97 | path: '/',
98 | });
99 | }
100 | };
101 |
102 | const deslogado = (to, from, next) => {
103 | if (!localStorage.getItem('AUTENTICADO')) {
104 | next();
105 | } else {
106 | next({
107 | path: '/dashboard',
108 | });
109 | }
110 | };
111 |
112 | export default [
113 | {
114 | path: '/login',
115 | component: Login,
116 | beforeEnter: multiguard([deslogado]),
117 | },
118 | {
119 | path: '/dashboard',
120 | component: Dashboard,
121 | beforeEnter: multiguard([logado]),
122 | children: [
123 | { path: '/', component: DashboardHome },
124 | ],
125 | },
126 | ];
127 | ```
128 |
129 | * Adicionamos o **deslogado**, pois dessa forma o usuário que já esta na aplicação não consigo acessar o login novamente.
130 |
131 | * Futuramente iremos implementar a mesma lógica no **Header** para não exibir as opções de **entrar** e **registrar**, e sim para ir no **dashboard**.
132 |
133 | Dessa forma podemos fazer vários tipos e reaproveitar verificações.
134 |
135 | Na próxima seção iremos explicar um pouco sobre transições em rotas, estaremos te esperando!
136 |
137 | [Próxima Seção](./5-Transições%20no%20VueRouter.md)
138 |
--------------------------------------------------------------------------------
/docs/tutorial/4-Vue Router/5-Transições no VueRouter.md:
--------------------------------------------------------------------------------
1 | # Transições no VueRouter
2 |
3 | O **VueRouter** aceita o componente **transition** nas rotas, dessa forma conseguimos fazer animações diretamente na **rota**
4 |
5 | ## VueRouter Principal
6 |
7 | Podemos adicionar um **transition** em nosso **App.js**, por exemplo:
8 |
9 | `./src/App.vue`
10 |
11 | ```html
12 |
13 |
14 |
15 |
16 |
17 |
18 |
21 |
22 |
31 | ```
32 |
33 | ## VueRouter do Dashboard
34 |
35 | Agora vamos implementar um efeito parecido nas rotas filhas de **dashboard**:
36 |
37 | ```html
38 |
39 |
40 |
41 |
42 |
43 |
44 |
60 | ```
61 |
62 | No próximo capítulo iremos inicializar com **Vuex**, explicando o fluxo e implementando uma simples autenticação, nos vemos lá!
63 |
64 | [Próxima Seção](../5-Vuex/1-Gerenciamento%20de%20Estado.md)
65 |
--------------------------------------------------------------------------------
/docs/tutorial/5-Vuex/1-Gerenciamento de Estado.md:
--------------------------------------------------------------------------------
1 | # Gerenciamento de Estado
2 |
3 | Agora vamos introduzir sobre o **Vuex**, o **gerenciador de estado** do **Vue**. O **Vuex** pode ser relacionado com o **Redux**, mas possuem diferenças cruciais.
4 |
5 | Ele é um padrão de gerenciamento de estado + biblioteca para a. Ele serve como uma loja centralizada para todos os componentes em uma aplicação, com regras garantindo que o estado só possa ser mutado de forma previsível. Ou seja, dessa forma conseguimos salvar dados temporários que podem ser úteis ao longo da aplicação. Por exemplo, o id de um usuário ou produto, que precisamos consultar em vários componentes diferentes!
6 |
7 | ## Fluxo
8 |
9 |
10 |
11 |
12 |
13 | Todo o **Vuex** funciona em torno deste ciclo, mas, oque É esse ciclo você me pergunta:
14 |
15 | ## Vue Components
16 |
17 | Seria todos os nossos componentes **.vue**, seja ela **propriedade** ou **page** o **vuex** irá realizar uma série de ações até chegar novamente no nosso componente.
18 |
19 | Para mandar uma ação para o **vuex**, usamos o **dispatch**, que irá conter o nome para onde queremos mandar, e como segundo parâmetro o conteúdo.
20 |
21 | Exemplo:
22 |
23 | `dispatch('nome_da_action', { hello: world });`
24 |
25 | Podemos enviar o que quisermos, como objetos, booleanos, etc. **NÃO** recomendamos mandar **templates**.
26 |
27 | ## Action
28 |
29 | As actions é a onde o **dispatch** irá enviar o conteúdo. As actions servem para realizar código **assíncrono** no **Vuex**.
30 |
31 | Em caso de não ter necessidade de realizar código assíncrono, podemos apenas enviar o conteúdo diretamente para a **Mutation**.
32 |
33 | Depois de executarmos o que for preciso, vamos **commitar** para a **Mutation**, como o próprio nome sugere, ele que irá **mutar** o estado.
34 |
35 | Exemplo:
36 |
37 | `commit('nome_da_mutation', objeto);`
38 |
39 | * Para mandar para uma **action** usamos o **dispatch** e para uma **mutation** usamos o **commit**, possuem nomes diferentes exatamente para não confundir o desenvolvedor.
40 |
41 | ## Mutations
42 |
43 | Na **mutation**, teremos acesso ao **estado** do **Vuex**, assim conseguindo **mutar**. Iremos explicar detalhadamente na seção de **Mutations**.
44 |
45 | ## State
46 |
47 | Aqui é a onde estará os nossos estados, por exemplo:
48 |
49 | ```js
50 | state: {
51 | contador: 0
52 | }
53 | ```
54 |
55 | * Apenas isso? Sim!
56 |
57 | ## Getters
58 |
59 | Os **getters** funcionam com a mesma lógia das **computeds**, podemos fazer uma **cópia** do estado para modificação sem a **mutação** do **estado**
60 |
61 | ## Estrutura da Loja
62 |
63 | A estrutura de nossa loja é bem simples, nada distante do que já vimos no **Vue**:
64 |
65 | **Vue**
66 |
67 | ```js
68 | new Vue({
69 | data: {
70 |
71 | },
72 | methods: {
73 |
74 | },
75 | computed: {
76 |
77 | },
78 | });
79 | ```
80 |
81 | **Vuex**
82 |
83 | ```js
84 | new Vuex.Store({
85 | state: {
86 |
87 | },
88 | mutations: {
89 |
90 | },
91 | actions: {
92 |
93 | },
94 | getters: {
95 |
96 | },
97 | });
98 | ```
99 |
100 | * O **Vuex** **NÃO** irá substituir a estrutura dos componentes do **Vue**, é recomendável só utilizar o **Vuex** quando realmente necessitamos acessar um mesmo **conteúdo** em várias partes diferentes da **aplicação**.
101 |
102 | Na próxima seção, iremos implementar a **loja** em nosso projeto atual, nos vemos lá!
103 |
104 | [Próxima Seção](./2-Iniciando%20com%20Vuex.md)
--------------------------------------------------------------------------------
/docs/tutorial/5-Vuex/2-Iniciando com Vuex.md:
--------------------------------------------------------------------------------
1 | # Iniciando com Vuex
2 |
3 | Primeiramente, vamos adicionar o **Vuex** em nossa aplicação:
4 |
5 | `vue add vuex`
6 |
7 | * Usando o CLI do **Vue**, ele já ira estruturar o **Vuex**
8 |
9 | Na pasta gerada `./src/store.js`, podemos ver como ficou nossa **loja**:
10 |
11 | ```js
12 | import Vue from 'vue';
13 | import Vuex from 'vuex';
14 |
15 | Vue.use(Vuex);
16 |
17 | export default new Vuex.Store({
18 | state: {
19 | },
20 | mutations: {
21 | },
22 | actions: {
23 | },
24 | modules: {
25 | },
26 | });
27 | ```
28 |
29 | * Iniciamente na aplicação, iremos seguir este **padrão** de estrutura, mas no final da nossa seção do **Vuex** iremos apresentar **alternativas** mais robustas.
30 |
31 | O **Vuex** não restringe a estrutura do seu código, sendo possível implementar qualquer tipo de estrutura necessária. Em vez disso, ele impõe um conjunto de princípios recomendados para projetos de médio-grande porte:
32 |
33 | * O estado do nível do aplicativo é centralizado no store.
34 |
35 | * A única maneira de mudar o estado é confirmando (ou fazendo commit das) mutações, que são transações **síncronas**.
36 |
37 | * Os getters nos permitem uma facilidade muito grande para a formatação de conteúdos do **estado** no template.
38 |
39 | * A lógica assíncrona deve ser encapsulada e pode ser composta com ações, e podem ser feitas apenas nas **actions**.
40 |
41 | * Se o arquivo da loja for muito grande, basta começar a dividir as actions, mutations e getters em arquivos separados, podendo utilizar operadores de desconstrução do **JavaScript** sem problemas.
42 |
43 | Na próxima seção, iremos mostrar formas diferentes de implementar os **estados** em nossas aplicações, nos vemos lá!
44 |
45 | [Próxima Seção](./3-State.md)
--------------------------------------------------------------------------------
/docs/tutorial/5-Vuex/3-State.md:
--------------------------------------------------------------------------------
1 | # States
2 |
3 | Agora, vamos implementar o objeto **usuario**, para conseguirmos ter todos os dados sem precisar requisitar novamente a **API**.
4 |
5 | Primeiramente, vamos criar em nosso estado:
6 |
7 | ```js
8 | import Vue from 'vue';
9 | import Vuex from 'vuex';
10 |
11 | Vue.use(Vuex);
12 |
13 | export default new Vuex.Store({
14 | state: {
15 | usuario: {
16 | conta: '',
17 | senha: '',
18 | },
19 | },
20 | mutations: {
21 | },
22 | actions: {
23 | },
24 | modules: {
25 | },
26 | });
27 | ```
28 |
29 | * O estado do **Vuex** é criado **junto** com o que será montado na instância, no nosso caso **App.js**, então é possivel requisitar o localStorage diretamente, por exemplo:
30 |
31 | ```js
32 | import Vue from 'vue';
33 | import Vuex from 'vuex';
34 |
35 | Vue.use(Vuex);
36 |
37 | export default new Vuex.Store({
38 | state: {
39 | autenticado: localStorage.getItem('AUTENTICADO') || '',
40 | },
41 | });
42 | ```
43 |
44 | ## mapState
45 |
46 | Para conseguirmos acessar no template, iremos utilizar o **mapState**:
47 |
48 | ```js
49 | import { mapState } from 'vuex';
50 |
51 | export default {
52 | // ...
53 | computed: {
54 | ...mapState(['usuario']);
55 | },
56 | };
57 | ```
58 |
59 | * Estamos desconstruindo para conseguirmos utilizar outros conteúdos na nossa **computed**
60 |
61 | * o **mapState** precisa ficar na **computed** para que quando o valor que está no **store** for mudado, o **mapState** consiga escutar a alteração e exibir em tempo real no template.
62 |
63 | ## Aplicando no Projeto
64 |
65 | Em nossa aplicação, iremos retirar o nosso localStorage com os dados do usuário e substituir para o nosso usuário do estado:
66 |
67 | `./src/pages/Login.vue`
68 |
69 | ```js
70 |
88 | ```
89 |
90 | `./src/pages/Dashboard.vue`
91 |
92 | ```js
93 |
94 |
95 | Olá {{ usuario.conta }}!
96 | Drawer
97 |
98 |
99 |
100 |
150 | ```
151 |
152 | * Vamos exibir agora no template pelo `usuario.conta` e não por `conta`
153 |
154 | Podemos buscar outros conteúdos que estão no estado, por exemplo:
155 |
156 | ```js
157 | computed: {
158 | ...mapState([
159 | 'a'
160 | 'b',
161 | 'c',
162 | ]),
163 | },
164 | ```
165 | Na próxima seção iremos implementar o **dispatch** no Login, nos vemos lá!
166 |
167 | [Próxima Seção](./4-Actions.md)
168 |
169 |
170 |
--------------------------------------------------------------------------------
/docs/tutorial/5-Vuex/4-Actions.md:
--------------------------------------------------------------------------------
1 | ## Actions
2 |
3 | Agora iremos implementar nossa **action** do **usuario**.
4 |
5 | Primeiramente, vamos criar o **dispatch**:
6 |
7 | `./src/pages/Login.vue`
8 |
9 | ```js
10 |
32 | ```
33 |
34 | Agora precisamos criar a action **USUARIO_LOGADO** em nossa **loja**:
35 |
36 | `./src/store/index.js`
37 |
38 | ```js
39 | export default new Vuex.Store({
40 | // ...
41 | actions: {
42 | usuarioLogado(context, usuario) {
43 | context.commit('usuarioLogado', usuario);
44 | },
45 | },
46 | // ...
47 | });
48 | ```
49 |
50 | * O context terá tudo o que podemos precisar para executar na nossa action, no caso estamos utilizando o `commit` que irá mandar para nossa `mutation`.
51 |
52 | * O **usuario** é o que estamos recebendo do `dispatch`
53 |
54 | Podemos simplificar o uso também:
55 |
56 | ```js
57 | export default new Vuex.Store({
58 | // ...
59 | actions: {
60 | usuarioLogado({ commit }, usuario) {
61 | commit('usuarioLogado', usuario);
62 | },
63 | },
64 | // ...
65 | });
66 | ```
67 |
68 | Na próxima seção iremos criar a nossa **mutation**, nos vemos lá!
69 |
70 | [Próxima Seção](./5-Mutations.md)
--------------------------------------------------------------------------------
/docs/tutorial/5-Vuex/5-Mutations.md:
--------------------------------------------------------------------------------
1 | ## Mutations
2 |
3 | Agora iremos implementar nossa **mutation** do **usuario**.
4 |
5 | Vamos no nosso store:
6 |
7 | `./src/store/index.js`
8 |
9 | ```js
10 | import Vue from 'vue';
11 | import Vuex from 'vuex';
12 |
13 | Vue.use(Vuex);
14 |
15 | export default new Vuex.Store({
16 | state: {
17 | usuario: {
18 | conta: '',
19 | senha: '',
20 | },
21 | },
22 | actions: {
23 | usuarioLogado(context, usuario) {
24 | context.commit('usuarioLogado', usuario);
25 | },
26 | },
27 | mutations: {
28 | usuarioLogado(state, payload) {
29 | state.usuario = payload;
30 | },
31 | },
32 | modules: {
33 | },
34 | });
35 | ```
36 |
37 | * O primeira argumento, **state** é a forma que iremos acessar o nosso **estado**, assim causando **mutação**.
38 |
39 | * O segundo argumento, **payload** é tudo oque estamos recebendo da nossa **action**.
40 |
41 | Causando mutação, o estado irá emitir o evento para o **mapState** (podemos também acessar a loja diretamente por this.$store.state.usuario, por exemplo).
42 |
43 | Acessando o `/dashboard`, poderá ver que nosso `Olá ...` voltou a funcionar!
44 |
45 | * IMPORTANTE!: A loja só ira **existir** em quanto o usuario estiver navegando, ele NÃO possui o mesmo funcionamento do **localStorage**. Uma forma de resolver esse problema é sempre que App.vue for construido, requisitar o localStorage que está com o id do usuário, buscar o usuário na API e dar **dispach** para o **Vuex**, assim conseguimos fazer que a conta do usuário seja lembrada até ele querer deslogar.
46 |
47 | Exemplo:
48 |
49 | `./src/App.vue`
50 |
51 | ```js
52 |
53 |
54 |
55 |
56 |
57 |
58 |
72 | ```
73 |
74 | * Iremos ensinar a como configurar o **axios** e até mesmo usar o **http** padrão do **Vue**, não se preocupe.
75 |
76 | Na próxima seção, iremos introduzir o conteúdo sobre **Getters**, nos vemos lá!
77 |
78 | [Próxima Seção](./6-Getters.md)
--------------------------------------------------------------------------------
/docs/tutorial/5-Vuex/6-Getters.md:
--------------------------------------------------------------------------------
1 | # Getters
2 |
3 | Os **getters** funcionam da mesma forma que as **computeds**, e no nosso caso iremos usar para concatenar a string que será exibida no nosso `/dashboard`:
4 |
5 | ```js
6 | import Vue from 'vue';
7 | import Vuex from 'vuex';
8 |
9 | Vue.use(Vuex);
10 |
11 | export default new Vuex.Store({
12 | state: {
13 | usuario: {
14 | conta: '',
15 | senha: '',
16 | },
17 | },
18 | actions: {
19 | usuarioLogado(context, usuario) {
20 | context.commit('usuarioLogado', usuario);
21 | },
22 | },
23 | mutations: {
24 | usuarioLogado(state, payload) {
25 | state.usuario = payload;
26 | },
27 | },
28 | getters: {
29 | usuarioBemVindo(state) {
30 | return `Olá ${state.usuario.conta}!`;
31 | },
32 | },
33 | modules: {
34 | },
35 | });
36 | ```
37 |
38 | Dessa forma, podemos utilizar o `usuarioBemVindo` no template:
39 |
40 | `./src/pages/Dashboard.vue`
41 |
42 | ```js
43 |
44 |
45 | {{ usuarioBemVindo }}
46 | Drawer
47 |
48 |
49 |
50 | // ...
51 |
52 | import { mapGetters } from 'vuex';
53 |
54 | computed: {
55 | ...mapGetters(['usuarioBemVindo']),
56 | },
57 | ```
58 |
59 | * Trocamos o **mapState** por **mapGetters**
60 |
61 | Na próxima seção vamos mostrar como melhorar nossa estrutura, nos vemos lá!
62 |
63 | [Próxima Seção](./7-Estrutura.md)
--------------------------------------------------------------------------------
/docs/tutorial/5-Vuex/7-Estrutura.md:
--------------------------------------------------------------------------------
1 | # Estrutura
2 |
3 | Iremos melhor o nosso **store**, para a seguinte estrutura:
4 |
5 | ```js
6 | index.js
7 | state.js
8 | actions.js
9 | mutations.js
10 | mutations_types.js
11 | getters.js
12 | ```
13 |
14 | `./src/store/index.js`
15 |
16 | ```js
17 | import Vue from 'vue';
18 | import Vuex from 'vuex';
19 |
20 | import state from './state';
21 | import actions from './actions';
22 | import mutations from './mutations';
23 | import getters from './getters';
24 |
25 | Vue.use(Vuex);
26 |
27 | export default new Vuex.Store({
28 | ...state,
29 | ...actions,
30 | ...mutations,
31 | ...getters,
32 | });
33 | ```
34 |
35 | Agora iremos passar o conteudo de nosso **store** para cada arquivo:
36 |
37 | `./src/store/state.js`
38 |
39 | ```js
40 | export default {
41 | state: {
42 | usuario: {
43 | conta: '',
44 | senha: '',
45 | },
46 | },
47 | };
48 | ```
49 |
50 | `./src/store/actions.js`
51 |
52 | ```js
53 | import types from './mutations_types';
54 |
55 | export default {
56 | actions: {
57 | usuarioLogado(context, usuario) {
58 | context.commit(types.USUARIO_LOGADO, usuario);
59 | },
60 | },
61 | };
62 |
63 | ```
64 |
65 | `./src/store/getters.js`
66 |
67 | ```js
68 | export default {
69 | getters: {
70 | usuarioBemVindo(state) {
71 | return `Olá ${state.usuario.conta}!`;
72 | },
73 | },
74 | };
75 | ```
76 |
77 | `./src/store/mutations.js`
78 |
79 | ```js
80 | import types from './mutations_types';
81 |
82 | export default {
83 | mutations: {
84 | [types.USUARIO_LOGADO](state, payload) {
85 | state.usuario = payload;
86 | },
87 | },
88 | };
89 | ```
90 |
91 | `./src/store/mutations_types.js`
92 |
93 | ```js
94 | export default {
95 | USUARIO_LOGADO: 'USUARIO_LOGADO',
96 | };
97 | ```
98 |
99 | * Mapeando as mutations, conseguimos ter uma organização melhor.
100 |
101 | No próxima capítulo iremos mostrar algumas bibliotecas que podem ser o **game changer** de seu projeto, nos vemos lá!
102 |
103 | [Próxima Seção](./8-Modules.md)
104 |
--------------------------------------------------------------------------------
/docs/tutorial/5-Vuex/8-Modules.md:
--------------------------------------------------------------------------------
1 | # Módulos
2 |
3 | Não iremos aplicar os módulos do **Vuex** em nosso projeto pois ele é pequeno demais no momento para essa necessidade, mas mostrar novos recursos nunca é demais!
4 |
5 | Os módulos do **Vuex** são basicamente "namespaces" em uma camada mais no objeto da nossa loja, assim conseguimos dividir grupos e estruturar de uma forma mais satisfatória nossos projetos.
6 |
7 | Uma estrutura básica usando módulos:
8 |
9 | ```js
10 | const moduloA = {
11 | state: () => ({ ... }),
12 | mutations: { ... },
13 | actions: { ... },
14 | getters: { ... }
15 | }
16 |
17 | const moduloB = {
18 | state: () => ({ ... }),
19 | mutations: { ... },
20 | actions: { ... }
21 | }
22 |
23 | const store = new Vuex.Store({
24 | modules: {
25 | a: moduloA,
26 | b: moduloB
27 | }
28 | })
29 |
30 | store.state.a // -> Conseguimos acesso ao state do módulo 'a'
31 | store.state.b // -> Conseguimos acesso ao state do módulo 'b'
32 | ```
33 |
34 | * O primeiro argumento recebido é o estado local do módulo, **não o do root**. Para acessarmos o root, podemos facilmente desconstruir o objeto:
35 |
36 | ```js
37 | const modulo = {
38 | // ...
39 | actions: {
40 | actionNoModulo ({ state, commit, rootState }) {
41 | commit('continuar')
42 | }
43 | }
44 | // ...
45 | }
46 | ```
47 |
48 | * Sendo os getters o terceiro argumento.
49 |
50 | * Utilizando `namespaced: true`, nossos módulos não serão mais registrados em um namespace global, dessa forma conseguimos componentes mais independentes um do outro.
51 |
52 | ```js
53 | const store = new Vuex.Store({
54 | modules: {
55 | grupo: {
56 | namespaced: true,
57 | state: () => ({ he4rt: "He4rt" }), // o estado do módulo já está aninhado e não é afetado pela opção de namespace
58 | getters: {
59 | getHe4rt (state) { return state.he4rt } // -> getters['grupo/getHe4rt']
60 | },
61 | mutations: {
62 | setHe4rt (state) { state.he4rt += " Developers" } // -> commit('grupo/setHe4rt')
63 | },
64 | }
65 | }
66 | })
67 | ```
68 |
69 | Na próxima seção, iremos começar a mostrar bibliotecas adicionais para auxiliar o seu desenvolvimento! Nos vemos lá!
70 |
71 | [Próxima Seção](../6-Bibliotecas%20Adicionais/1-Vuelidate.md)
--------------------------------------------------------------------------------
/docs/tutorial/6-Bibliotecas Adicionais/1-Vuelidate.md:
--------------------------------------------------------------------------------
1 | # Vuelidate
2 |
3 | **Vuelidate** é uma biblioteca para validação dos dados de entrada **v-model**
4 |
5 | Com ele, conseguimos fazer validação de formulários de uma forma intuitiva.
6 |
7 | ## Adicionando no Projeto
8 |
9 | `yarn add vuelidate`
10 |
11 | Agora utilizando o `Vue.use()` iremos registrar nossa **biblioteca**:
12 |
13 | `./src/main.js`
14 |
15 | ```js
16 | import Vue from 'vue';
17 | import Vuelidate from 'vuelidate';
18 | import App from './App.vue';
19 | import vuetify from './plugins/vuetify';
20 | import router from './plugins/vuerouter';
21 | import store from './store';
22 |
23 | Vue.config.productionTip = false;
24 |
25 | Vue.use(Vuelidate);
26 |
27 | new Vue({
28 | vuetify,
29 | router,
30 | store,
31 | render: (h) => h(App),
32 | }).$mount('#app');
33 | ```
34 |
35 | * O **Vuelidate** não tem necessidade de registrar dentro da instância **Vue**, igual o **Vuetify**, **VueRouter** e **Vuex**.
36 |
37 | Antes de aplicar as validações no formulário de login, vamos fazer o formulário de registrar!
38 |
39 | ``./src/routes.js`
40 |
41 | ```js
42 | import Register from './pages/Register.vue';
43 | // ...
44 | {
45 | path: '/register',
46 | component: Register,
47 | beforeEnter: multiguard([deslogado]),
48 | },
49 | // ...
50 | ```
51 |
52 | `./src/pages/Register.vue`
53 |
54 | ```js
55 |
56 |
57 |
58 |
62 |
66 |
71 |
72 |
77 | Cadastre sua Conta!
78 |
79 |
80 |
81 |
88 |
95 |
102 |
103 |
104 |
105 | Já possui uma conta? Clique
106 |
107 |
110 | aqui
111 |
112 |
113 |
114 |
115 | Entrar
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
144 | ```
145 |
146 | Bem parecido com o nosso **Login**, agora vamos aplicar o **Vuelidate**
147 |
148 | ## Validators
149 |
150 | O **Vuelidate** trabalha com **validators**, ele irá **escutar** toda alteração no **v-model** e retornando **true** ou *false** dependendo do que estiver como **condição** nos **validators**
151 |
152 | Vamos fazer o nosso **validator** do **Register.vue**:
153 |
154 | ```js
155 |
198 | ```
199 |
200 | * Importamos os **validators**.
201 |
202 | * Colocamos o tipo de validação.
203 |
204 | * Verificamos se o formulário é válido no **enviarFormulario()**.
205 |
206 | * Também podemos utilizar as validações em nosso template:
207 |
208 | ```html
209 |
210 |
Digite a senha!
211 |
212 | ```
213 |
214 | Recomendamos FORTEMENTE que olhe a documentação do [Vuelidate](https://vuelidate.js.org/#sub-form-submission).
215 |
216 | Na próxima seção iremos apresentar a forma de fazer **internacionalização** no **Vue**!
217 |
218 | [Próxima Seção](./2-Vuei18n.md)
219 |
--------------------------------------------------------------------------------
/docs/tutorial/6-Bibliotecas Adicionais/2-Vuei18n.md:
--------------------------------------------------------------------------------
1 | # Vue i18n
2 |
3 | O [Vuei18n](https://kazupon.github.io/vue-i18n/) é um plugin para internacionalização que o **Vue** nos disponibiliza.
4 |
5 | ## Estrutura
6 |
7 | Todas as mensagens irão ficar em arquivos como **objetos literais**
8 |
9 | ```js
10 | const messages = {
11 | en: {
12 | message: {
13 | hello: 'Hello'
14 | }
15 | },
16 | pt_BR: {
17 | message: {
18 | hello: 'Olá!'
19 | }
20 | }
21 | }
22 | ```
23 |
24 | E exibir no template como:
25 |
26 | ```js
27 |
{{ $t('message.hello') }}
28 | ```
29 |
30 | Dessa forma, tudo oque for estático em nossa aplicação irá ser exibido a partir de um objeto, então:
31 |
32 | * É recomendável começar o projeto JÁ utilizando o i18n, pois para reestruturar tudo pode ser uma dor de cabeça
33 |
34 | * Mensagens em certas linguagens podem ficar muito grande ou muito pequeno do que o originalmente esperado.
35 |
36 | * Apenas utilize i18n se o seu projeto seja **REALMENTE** internacional, pois pode perder muito tempo no projeto sem necessidade.
37 |
38 | * NÃO iremos mostrar a aplicação do i18n no nosso projeto atual pois iria precisar refazer algumas coisas, o que quebraria a ideia do curso, mas fique á vontade para utilizá-lo!
39 |
40 | Na próxima seção iremos aplicar notificações com AWN, nos vemos lá!
41 |
42 | [Próxima Seção](./3-VueAWN.md)
--------------------------------------------------------------------------------
/docs/tutorial/6-Bibliotecas Adicionais/3-VueAWN.md:
--------------------------------------------------------------------------------
1 | # Vue Awesome Notifications
2 |
3 | O [Vue Awesome Notifications](https://f3oall.github.io/awesome-notifications/docs/toasts/general) permite criar notificações interativas para o usuário.
4 |
5 | ## Instalação no Projeto
6 |
7 | Comando: `yarn add vue-awesome-notifications`
8 |
9 | `./src/main.js`
10 |
11 | ```js
12 | import Vue from 'vue';
13 | import VueAWN from 'vue-awesome-notifications';
14 |
15 | Vue.use(VueAWN, {});
16 | // ...
17 | ```
18 |
19 | Vamos adicionar o css global:
20 |
21 | `./src/App.vue`
22 |
23 | ```js
24 |
34 | ```
35 |
36 | Vamos utilizar o AWS para mostrar a verificação de nosso formulário:
37 |
38 | `./src/pages/Register.vue`
39 |
40 | ```js
41 | // ...
42 | methods: {
43 | enviarFormulario() {
44 | if (!this.$v.$invalid) {
45 | // POST para a rota em uma possível API
46 | localStorage.setItem('AUTENTICADO', true);
47 | this.$store.dispatch('usuarioLogado', {
48 | conta: this.conta,
49 | senha: this.senha,
50 | });
51 | this.$router.push('/dashboard');
52 | } else {
53 | this.$awn.alert('Formulário Inválido');
54 | }
55 | },
56 | },
57 | // ...
58 | ```
59 |
60 | * Usando o **$awn** conseguimos emitir os eventos customizáveis.
61 |
62 | Recomendamos MUITO que acesse a documentação do [AWN](https://f3oall.github.io/awesome-notifications/docs/toasts/general).
63 |
64 | Na próxima seção, iremos mostrar como utilizar **Dark Theme** de forma facilitada no **Vue**, nos vemos lá!
65 |
66 | * Agora iremos apenas mostrar outras bibliotecas que podem ajudar o desenvolvimento de aplicações, vamos voltar a mecher no projeto apenas na seção de **Testes e Documentação**
67 |
68 | [Próxima Seção](./4-VueDarkMode.md)
--------------------------------------------------------------------------------
/docs/tutorial/6-Bibliotecas Adicionais/4-VueDarkMode.md:
--------------------------------------------------------------------------------
1 | # Vue Dark Mode
2 |
3 | O VueDarkMode é um conjunto de componentes projetados para facilitar a projeção de transiçõe sentre white mode e dark mode.
4 |
5 | ## Como instalar
6 |
7 | `yarn add @growthbunker/vuedarkmode`
8 |
9 | `./src/main.js`
10 |
11 | ```js
12 | import Vue from "vue";
13 | import VueDarkMode from "@growthbunker/vuedarkmode";
14 |
15 | Vue.use(VueDarkMode);
16 | ```
17 |
18 | O **VueDarkMode** possui:
19 |
20 | - Alerts
21 | - Avatars
22 | - Badges
23 | - Buttons
24 | - Dividers
25 | - Headings
26 | - Icons
27 | - Progress Bar
28 | - Spinners
29 | - Toasts
30 | - Checkboxes
31 | - Images
32 | - Inputs
33 | - Numerics
34 | - Radios
35 | - Selects
36 | - Tabs
37 | - Textareas
38 | - Toggles
39 |
40 | Usando os **componentes*, basta passar as **propriedades** que estão na **documentação** de cada **componente**.
41 |
42 | Na próxima seção, iremos mostrar como utilizar o **VueResource**, te vemos lá!
43 |
44 | [Próxima Seção](./5-VueResource.md)
--------------------------------------------------------------------------------
/docs/tutorial/6-Bibliotecas Adicionais/5-VueResource.md:
--------------------------------------------------------------------------------
1 | # Vue Resource
2 |
3 | O **VueResource** é um http client para o **Vue**. Em uma das seções já mostramos em como configurar o **http** para utilizar junto com o **axios**, mas podemos usar o próprio **VueResource**
4 |
5 | Instalação: `yarn add vue-resource`
6 |
7 | ## Configuração
8 |
9 | ```js
10 | new Vue({
11 | http: {
12 | root: '/root',
13 | headers: {
14 | Authorization: 'Bearer'.
15 | }.
16 | }.
17 | });
18 | ```
19 |
20 | ## Exemplo
21 |
22 | ```js
23 | this.$http.get('/url')
24 | .then(res => {
25 |
26 | console.log(res.body());
27 | }, res => {
28 | console.error(err);
29 | }
30 | ```
31 |
32 | Para mais detalhes sobre o **VueLoader** clique [aqui](https://github.com/pagekit/vue-resource)
33 |
34 | Na próxima seção, iremos mostrar como utilizar o **TypeScript** no **Vue** com o auxílio do **PropertyDecorator**, nos vemos lá!
35 |
36 | [Próxima Seção](./6-VuePropertyDecorator.md)
--------------------------------------------------------------------------------
/docs/tutorial/6-Bibliotecas Adicionais/6-VuePropertyDecorator.md:
--------------------------------------------------------------------------------
1 | # Vue Property Decorator
2 |
3 | No **Vue-CLI** é posível escolher a opção de usar o **Vue** com **Typescript**, e o [Property Decorator](https://github.com/kaorun343/vue-property-decorator) melhora esta experiência.
4 |
5 | Exemplo:
6 |
7 | ```js
8 | import { Vue, Component, Emit } from 'vue-property-decorator';
9 |
10 | @Component
11 | export default class He4rtComponent extends Vue {
12 | he4rt = 'He4rt';
13 |
14 | @Emit()
15 | Dev() {
16 | this.he4rt += ' Developers';
17 | }
18 | };
19 | ```
20 |
21 | Saiba mais sobre o **Vue** com **Typescript** clicando [aqui](https://br.vuejs.org/v2/guide/typescript.html).
22 |
23 | Na próxima seção, iremos mostrar como utilizar o **awesome icons** no **Vue**, nos vemos lá!
24 |
25 | [Próxima Seção](./7-VueFontAwesome.md)
--------------------------------------------------------------------------------
/docs/tutorial/6-Bibliotecas Adicionais/7-VueFontAwesome.md:
--------------------------------------------------------------------------------
1 | # Vue Awesome Icons
2 |
3 | O [Vue FontAwesome](https://github.com/FortAwesome/vue-fontawesome) é o port do conhecido [FontAwesome](https://fontawesome.com/icons?d=gallery), assim conseguimos utilizar as fontes no **Vue**:
4 |
5 | ```js
6 | yarn add @fortawesome/fontawesome-svg-core
7 | yarn add @fortawesome/free-solid-svg-icons
8 | yarn add @fortawesome/vue-fontawesome
9 | ```
10 |
11 | O exemplo recomendado:
12 |
13 | ```js
14 | import Vue from 'vue';
15 | import { library } from '@fortawesome/fontawesome-svg-core';
16 | import { faUserSecret } from '@fortawesome/free-solid-svg-icons';
17 | import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
18 |
19 | library.add(faUserSecret);
20 |
21 | Vue.component('font-awesome-icon', FontAwesomeIcon);
22 | ```
23 |
24 | * Registrando o componente **font-awesome-icon** podemos usá-lo em nosso template:
25 |
26 | ```html
27 |
28 | ```
29 |
30 | * Para usar os ícones sem ser em usa versão default(solid), verifique a documentação.
31 |
32 | * Registre os ícones usando o `library.add(faIcone)`
33 |
34 | Na próxima seção, iremos introduzir sobre como utilizar o **Jest** no **Vue**, te vemos lá!
35 |
36 | [Próxima Seção](./8-VuexClassModules.md)
37 |
--------------------------------------------------------------------------------
/docs/tutorial/6-Bibliotecas Adicionais/8-VuexClassModules.md:
--------------------------------------------------------------------------------
1 | # Vuex Class Modules
2 |
3 | O [Vuex Class Modules](https://github.com/gertqin/vuex-class-modules) é um pacote que traz type-safe em conjunto com o Typescript sendo simples para o **Vuex**.
4 |
5 | Para adicionar em nosso projeto, utilize o comando `yarn add vuex-class-modules`
6 |
7 | Com ele, conseguimos utilizar os módulos do **Vuex** de uma forma diferente:
8 |
9 | `modulo-usuario.ts`
10 |
11 | ```ts
12 | import { VuexModule, Module, Mutation, Action } from "vuex-class-modules";
13 |
14 | @Module
15 | class ModuloUsuario extends VuexModule {
16 | nome = "Joãozinho123";
17 |
18 | get nomeInteiro() {
19 | return this.nome += "456789";
20 | }
21 |
22 | @Mutation
23 | setNome(nome: string) {
24 | this.nome = nome;
25 | }
26 |
27 | @Action
28 | async carregarUsuarioNome() {
29 | const { nome } = await fetchUsuario();
30 | this.setNome(nome);
31 | }
32 | }
33 |
34 | //Registrar o módulo
35 | import store from "@/store";
36 | export const moduloUsuario = new ModuloUsuario({ store, name: "usuario" });
37 | ```
38 |
39 | `MeuComponente.vue`
40 |
41 | ```ts
42 | import Vue from "vue";
43 | import { ModuloUsuario } from "path/to/modulo-usuario.ts";
44 |
45 | export class MeuComponente extends Vue {
46 | get nome() {
47 | return ModuloUsuario.nome; // -> é igual a store.state.usuario.nome
48 | }
49 | get nomeInteiro() {
50 | return ModuloUsuario.fullName; // -> é igual a store.getters["usuario/nomeInteiro]
51 | }
52 |
53 | mounted() {
54 | ModuloUsuario.carregarUsuarioNome(); // -> é igual a store.dispatch("usuario/carregarUsuarioNome")
55 | }
56 | }
57 | ```
58 |
59 | * Chamamos o this.setNome(nome) na Action pois o fluxo do Vuex necessita de commitar para a mutation, por isso não podemos fazer this.nome = nome dentro de uma action.
60 |
61 | * Precisamos dos getters em nossos componentes pois dessa forma em caso aconteça uma mutação em nosso store em quanto um item do template está sendo exibido o seu conteúdo não fica estático e acaba sendo aplicado a mundaça no template.
62 |
63 | [Próxima Seção](./9-AntDesignVue.md)
64 |
--------------------------------------------------------------------------------
/docs/tutorial/6-Bibliotecas Adicionais/9-AntDesignVue.md:
--------------------------------------------------------------------------------
1 | # Ant Design Vue
2 |
3 | [Ant](https://www.antdv.com/docs/vue/introduce/) é uma framework que possui componentes de alta qualidade para os seus projetos, sendo essa sua versão para o Vue, funcionando de uma forma diferente do [Vuetify](https://vuetifyjs.com/).
4 |
5 | Para instalar em um projeto já existente:
6 |
7 | `vue add ant-design`
8 |
9 | Para um novo projeto:
10 |
11 | `vue create antd-demo`
12 |
13 | Apenas instalar a dependência:
14 |
15 | `yarn add ant-design-vue`
16 |
17 | O Ant exige que se instale os componentes, vamos usar o exemplo utilizando o [Botão](https://www.antdv.com/components/button/):
18 |
19 | ```js
20 | import { Button } from 'ant-design-vue';
21 | Vue.use(Button);
22 | ```
23 |
24 | Na próxima seção, iremos introduzir sobre como utilizar o **Jest** no **Vue**, te vemos lá!
25 |
26 | [Próxima Seção](../7-Testes%20e%20Storybook/1-Jest%20no%20Vue.md)
27 |
--------------------------------------------------------------------------------
/docs/tutorial/7-Testes e Storybook/1-Jest no Vue.md:
--------------------------------------------------------------------------------
1 | # Jest no Vue
2 |
3 | O Vue-Tests-Utils é uma coleção de ferramentas do **Vue** para **testes**.
4 |
5 | Ele possui disponível os seguintes comandos:
6 |
7 | ```bash
8 | # unit testing
9 | vue add @vue/unit-jest
10 |
11 | # or:
12 | vue add @vue/unit-mocha
13 |
14 | # end-to-end
15 | vue add @vue/e2e-cypress
16 |
17 | # or:
18 | vue add @vue/e2e-nightwatch
19 | ```
20 |
21 | ## Jest
22 |
23 | O [Jest](https://jestjs.io/pt-BR/) é um poderoso Framework de Testes em JavaScript com um foco na simplicidade. Pelo VueCLI o **Jest** já vem configurado, assim sendo temos que apenas escrever os testes!
24 |
25 | ## Adicionando no Projeto
26 |
27 | Vamos utilizar o comando:
28 |
29 | `vue add @vue/unit-jest`
30 |
31 | Os arquivos gerados são:
32 |
33 | `jest.config.js`
34 |
35 | É na onde está o nosso preset do **JestVue**
36 |
37 | `./tests`
38 |
39 | É a onde ficará nossos testes do **Jest**
40 |
41 | `./tests/unit/example.spec.js`
42 |
43 | Todo arquivo de teste possui **spec.js**, para o **Jest** entender quais são os arquivos de **testes**.
44 |
45 | ```js
46 | import { shallowMount } from '@vue/test-utils';
47 | import HelloWorld from '@/components/HelloWorld.vue';
48 |
49 | describe('HelloWorld.vue', () => {
50 | it('renders props.msg when passed', () => {
51 | const msg = 'new message';
52 | const wrapper = shallowMount(HelloWorld, {
53 | propsData: { msg },
54 | });
55 | expect(wrapper.text()).toMatch(msg);
56 | });
57 | });
58 | ```
59 |
60 | Esse teste gerado é o **default**, no caso ele **monta** o componente que deletamos no ínicio do nosso projeto, o *HelloWorld**, passa uma **propriedade** por padrão, no caso **msg**, e **espera**(expect) encontrar esse texto no **componente**.
61 |
62 | * No nosso curso, iremos apenas mostrar como realizar testes no **Vue**, e não todo o **conceito** envolvido.Se quiser ler mais sobre, clique [aqui](https://medium.com/trainingcenter/uma-vis%C3%A3o-geral-de-testes-em-javascript-em-2018-8484154caf63).
63 |
64 | ## Criando testes
65 |
66 | Primeiramente vamos renomear nosso arquivo para `Home.spec.js` e substituir seu conteúdo para:
67 |
68 | ```js
69 | import Vue from 'vue';
70 | import Vuetify from 'vuetify';
71 | import { shallowMount, createLocalVue } from '@vue/test-utils';
72 | import Home from '@/pages/Home.vue';
73 |
74 | Vue.use(Vuetify); // Dessa forma, o nosso localVue irá conter o Vuetify
75 |
76 | describe('Home', () => {
77 | const localVue = createLocalVue();
78 |
79 | const wrapper = shallowMount(Home, {
80 | localVue,
81 | });
82 |
83 | it('home existe', () => {
84 | expect(wrapper.isVueInstance()).toBe(true);
85 | });
86 | });
87 | ```
88 |
89 | * Para rodar os testes, utiliza o comando `yarn test:unit`
90 |
91 | * Criando o localVue podemos anexar as outras bibliotecas de nossa aplicação nos testes.
92 |
93 | * Nesse caso, temos um teste simples se o componente é uma instância **Vue**.
94 |
95 | * Sempre que o seu componente tiver bibliotecas externas, (Vue i18n, por exemplo), pesquise sobre como realizer os **mocks**.
96 |
97 | * Você támbem pode fazer um **setup.js** com as configurações dos **testes**.
98 |
99 | * É possível procurar as classes **css** com o **jest**, não dependendo do nome do **componente**.
100 |
101 | Vamos fazer outros testes agora, um pouco mais elaborados:
102 |
103 | ## Header pertence ao componente
104 |
105 | ```js
106 | it('header.vue está no componente', () => {
107 | expect(wrapper.find('.header-stub').exists());
108 | });
109 | ```
110 |
111 | * Todo componente que está dentro de outro nos testes **sem ser montado** possui o final **-stub**.
112 |
113 | * Nesse teste, estamos apenas verificando se o **Header** é um componente de **Home**
114 |
115 | ## Texto do Vue4Noobs
116 |
117 | ```js
118 | it('Vue4Noobs está sendo exibido', () => {
119 | const noobs = wrapper.find('p').text();
120 | expect(noobs).toBe('Vue4Noobs');
121 | });
122 | ```
123 |
124 | * Estamos esperando que o conteúdo da tag **p** seja **Vue4Noobs**.
125 |
126 | Na próxima seção, iremos mostrar como utilizar o **Cypress** no **Vue**, nos vemos lá!
127 |
128 | [Próxima Seção](./2-Cypress%20no%20Vue.md)
129 |
130 |
--------------------------------------------------------------------------------
/docs/tutorial/7-Testes e Storybook/2-Cypress no Vue.md:
--------------------------------------------------------------------------------
1 | # Cypress no Vue
2 |
3 | O Cypress é uma ferramente para testes e2e, dessa forma não precisamos "testar na mão", porquê não ter esses testes documentados? Dessa forma conseguimos evitar imprevistos em nossas aplicações frontend.
4 |
5 | * O **Vue** tambem possui suporte para o [NightWatch](https://nightwatchjs.org/)
6 |
7 | Para adicionar o [Cypress](https://www.cypress.io/) em nosso projeto, iremos usar o seguinte comando:
8 |
9 | `vue add @vue/e2e-cypress`
10 |
11 | Os arquivos gerados:
12 |
13 | `cypress.json`
14 |
15 | Entrypoint para os testes
16 |
17 | `./tests/e2e/specs/`
18 |
19 | Onde ficará nossos testes
20 |
21 | `./tests/e2e/specs/index.js`
22 |
23 | ```js
24 | describe('My First Test', () => {
25 | it('Visits the app root url', () => {
26 | cy.visit('/');
27 | cy.contains('h1', 'Welcome to Your Vue.js App');
28 | });
29 | });
30 | ```
31 |
32 | * Neste teste, é visitado a rota `/` procurando pelo h1 que contén `Welcome to Your Vue.js App`.
33 |
34 | * Renomeie o teste de `test.js` para `landing.js`.
35 |
36 | Agora vamos reformular para a nossa página:
37 |
38 | ```js
39 | describe('Página Inicial', () => {
40 | it('Visitando a página inicial', () => {
41 | cy.visit('/');
42 | cy.contains('span', 'Pela: He4rt Developers');
43 | });
44 | it('Indo para o repositório', () => {
45 | cy.visit('/');
46 | cy.contains('Repositório').click();
47 | });
48 | it('Indo para o discord da He4rt', () => {
49 | cy.visit('/');
50 | cy.contains('He4rt Discord').click();
51 | });
52 | });
53 | ```
54 |
55 | * O primeiro verifica se o span no site possui o conteúdo `Pela: He4rt Developers`.
56 |
57 | * O segundo verifica se o botão Repositório existe e abre.
58 |
59 | * O terceiro verifica se o botão He4rt Discord existe e abre.
60 |
61 | Agora vamos criar o `register.js`, com o seguinte:
62 |
63 | ```js
64 | describe('Registrar', () => {
65 | it('Criando conta', () => {
66 | cy.visit('/register');
67 | cy.get('.conta').type('novout@hotmail.com');
68 | cy.get('.senha').type('123456789');
69 | cy.get('.repetirSenha').type('123456789');
70 | cy.contains('Entrar').click();
71 | cy.contains('Olá novout@hotmail.com');
72 | });
73 | });
74 | ```
75 |
76 | * O Cypress irá colocar os dados necessários e entrar no dashboard
77 |
78 | Após rodarmos o comando `yarn test:e2e`, abrirá a segunte tela:
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | * Para executar os testes basta clicar no nome deles ou em **Rodar todos os testes**.
89 |
90 | * O **Cypress** tem muitos recursos disponíveis, recomendamos muito que dê uma olhada na [documentação](https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Cypress-Can-Be-Simple-Sometimes).
91 |
92 | Na próxima seção, iremos mostrar como configurar o **Storybook** em nosso projeto, nos vemos lá!
93 |
94 | [Próxima Seção](./3-Storybook.md)
--------------------------------------------------------------------------------
/docs/tutorial/7-Testes e Storybook/3-Storybook.md:
--------------------------------------------------------------------------------
1 | # Storybook
2 |
3 | O [Storybook](https://storybook.js.org/) é uma ferramenta para o desenvolvimento de componentes de interface do usuário isolados para React, Vue e Angular. Torna a criação de UIs impressionantes organizada e eficiente.
4 |
5 | ## Utilizando no Vue
6 |
7 | Vamos utilizar o instalador global:
8 |
9 | `npx -p @storybook/cli sb init --type vue`
10 |
11 | Agora podemos criar nossas histórias em `./src/stories/**`
12 |
13 | Para rodar o **storybook**, usamos o comando `yarn storybook`
14 |
15 |
16 |
17 |
18 |
19 | * Não será explicado a sua utilização no projeto pois iria distânciar da ideia do 4noobs, apenas mostramos como utilizar no **Vue**, realmente recomendamos que dê uma lida sobre, pois pode ser muito **útil** para documentação de projetos.
20 |
21 | Na próxima seção, iremos começar a mostrar um pouco mais do **Ecossistema** do **Vue**, nos vemos lá!
22 |
23 | [Próxima Seção](../8%20-%20Ecossistema%20Vue/1%20-%20Nuxt.md)
24 |
--------------------------------------------------------------------------------
/docs/tutorial/8 - Ecossistema Vue/1 - Nuxt.md:
--------------------------------------------------------------------------------
1 | # Nuxt
2 |
3 | O [Nuxt](https://nuxtjs.org/) é uma framework **progressiva** para o **Vue**. Além de perfomático e modular ele permite o **SSR**(também é possível utilizar SPA com o Nuxt).Ele também já possui integrado o **VueRouter** e o **Vuex** com um funcionamento próprio.
4 |
5 | ## Criando Projeto
6 |
7 | Criar uma projeto **Nuxt** é bem facil, apenas utilizamos o **NPX**:
8 |
9 | `npx create-nuxt-app `
10 |
11 | * As configurações base, como `head`, `plugins` e opções gerais ficam em `nuxt.config.js` na raiz do projeto.
12 |
13 | ## Rotas
14 |
15 | O **Nuxt** gera **automaticamente** as **rotas**, dependendo da estrutura utilizada:
16 |
17 | pages/
18 | |>produto/
19 | |> _id.vue
20 | |> index.vue
21 |
22 | Será convertido para:
23 |
24 | ```js
25 | router: {
26 | routes: [
27 | {
28 | name: 'index',
29 | path: '/',
30 | component: 'pages/index.vue'
31 | },
32 | {
33 | name: 'produto',
34 | path: '/produto',
35 | component: 'pages/user/index.vue'
36 | },
37 | {
38 | name: 'produto_id',
39 | path: '/produto/:id',
40 | component: 'pages/produto/_id.vue'
41 | }
42 | ]
43 | }
44 | ```
45 |
46 | ## Plugins
47 |
48 | Para adicionar **bibliotecas externas** no **Nuxt**, podemos usar a pasta **plugins** e configurar o **nuxt.config.js**
49 |
50 | ```js
51 | import Vue from 'vue'
52 | import VueLib from 'vue-lib'
53 |
54 | Vue.use(VueLib)
55 | ```
56 |
57 | ```js
58 | export default {
59 | plugins: ['~/plugins/vue-lib']
60 | }
61 | ```
62 |
63 | ## Store
64 |
65 | O Nuxt muda a forma de como utilizar o **Vuex**, mapeando os arquivos dentro da pasta **store**:
66 |
67 | `store/index.js`
68 |
69 | ```js
70 | export const state = () => ({
71 | grupo: "He4rt";
72 | })
73 |
74 | export const mutations = {
75 | add(state) {
76 | state.grupo += " Developers"
77 | }
78 | }
79 | ```
80 |
81 | Para criar módulos, utilizamos `store/.js`:
82 |
83 | `store/game.js`
84 |
85 | ```js
86 | export const state = () => ({
87 | players: []
88 | })
89 | ```
90 |
91 | É a mesma coisa que:
92 |
93 | ```js
94 | new Vuex.Store({
95 | modules: {
96 | game: {
97 | namespaced: true,
98 | state: () => ({
99 | players: []
100 | })
101 | }
102 | }
103 | })
104 | ```
105 |
106 | ## Geração Estática
107 |
108 | Para gerarmos páginas estáticas com o **Nuxt**, executamos os seguintes passos:
109 |
110 | 1: Utilize a versão 2.14.0 ou maior
111 | 2: Coloque `target: "static"` em `nuxt.config.js`
112 | 3: Executa o comando `nuxt generate`
113 |
114 | Na próxima seção, iremos te apresentar o **Gridsome**, um gerador de **paginas estáticas**, nos vemos lá!
115 |
116 | ## Modulos
117 |
118 | O Nuxt possui um próprio site que exibe os [módulos feitos para nuxt](https://modules.nuxtjs.org/), onde conseguimos encontrar com facilidade integrações prontas com o Nuxt.js
119 |
120 | [Próxima Seção](./2%20-%20Gridsome.md)
121 |
--------------------------------------------------------------------------------
/docs/tutorial/8 - Ecossistema Vue/2 - Gridsome.md:
--------------------------------------------------------------------------------
1 | # Gridsome
2 |
3 | O [Gridsome](https://gridsome.org/docs/) é uma framework do **Vue** para construção de sites de forma rápida, sendo parecido em muitas partes com o **Gatsby** do **React**.
4 |
5 | ## Utilizando o Grisome
6 |
7 | `yarn global add @gridsome/cli`
8 |
9 | `gridsome create my-gridsome-site`
10 |
11 | ## Data
12 |
13 | O **Gridsome** utiliza o [GraphQL](https://gridsome.org/docs/data-layer/) para a importação de dados no seu projeto.
14 |
15 | Na próxima seção, iremos de mostrar o **VueNative**, uma forma de utilizar o **Vue** no **Mobile**, nos vemos lá!
16 |
17 | [Próxima Seção](./3%20-%20VueNative.md)
--------------------------------------------------------------------------------
/docs/tutorial/8 - Ecossistema Vue/3 - VueNative.md:
--------------------------------------------------------------------------------
1 | # VueNative
2 |
3 | O [VueNative](https://vue-native.io/) é uma estrutura para criar aplicativos móveis nativos entre plataformas usando JavaScript. Ele utiliza o próprio `react-native` por baixo dos panos para conseguirmos utilizar os componentes **Vue**.
4 |
5 | ## Instalação
6 |
7 | Recomendamos que leia a [documentação](https://vue-native.io/docs/installation.html) de instalação do **VueNative**.
8 |
9 | * O **VueNative** ainda está em desenvolvimento, falta amadurecimento da plataforma.
10 |
11 | * Também existe a opção do [VueNativeScript](https://nativescript-vue.org/) para o **mobile**.
12 |
13 | Na próxima seção iremos te mostrar como utilizar o **Vue** em conjunto com o **Electron**, nos vemos lá!
14 |
15 | [Próxima Seção](./4%20-%20VueElectron.md)
16 |
17 |
--------------------------------------------------------------------------------
/docs/tutorial/8 - Ecossistema Vue/4 - VueElectron.md:
--------------------------------------------------------------------------------
1 | # Vue-Electron Boilerplate
2 |
3 | O [VueElectron](https://github.com/SimulatedGREG/electron-vue) é um boilerplate configurado para utilizar o **Vue** junto com o [Electron](https://www.electronjs.org/).
4 |
5 | ## Instalação
6 |
7 | ```bash
8 | yarn global add vue-cli
9 | vue init simulatedgreg/electron-vue seu-projeto
10 | ```
11 |
12 | * Até a data quando essa seção foi feita(10/04/2020), o **Vuex** ainda não está funcionando em conjunto com o **VueElectron**.
13 |
14 | * Recomendamos que estude sobre o **Electron** para o maior aproveitamento da plataforma.
15 |
16 | ## vue-cli-electron-builder
17 |
18 | O Boilerplate acima está desatualizado e não é mais mantido, então recomendamos utilizar o [VueCli](https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/) para usar o electron.
19 |
20 | A sua utilização é bem simples, em um projeto já existênte execute o comando:
21 |
22 | `vue add electron-builder`
23 |
24 | Dessa forma, já ira ser criado o `background.js` que é o ponto de criação da interface inicial do electron
25 |
26 | * Podemos utilizar qualquer plugin externo como **vue-router**, **vuex**, **vuetify** e outros normalmente, diferente do boilerplate mostrado anteriormente.
27 |
28 | * Para utilizar os renders em conjunto com a instância vue, recomendamos que olhe a [documentação](https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/configuration.html#webpack-configuration) para a sua implementação.
29 |
30 | * O [Electron](https://www.electronjs.org/) por mais que seja sem dúvidas uma das tecnologias desktop de mais fácil implementação(se for comparado com as opções do C++) ainda sim exige um estudo a parte, a sua documentação é bem completa e possui diversos exemplos para seus recursos.
31 |
32 | O electron-builder já vem com algumas definições de reconhecimento de sistemas e de privilégios, mas o que recomendamos dar uma olhada a fundo é nisso daqui:
33 |
34 | ```js
35 | function createWindow() {
36 | win = new BrowserWindow({
37 | width: 800,
38 | height: 600,
39 | webPreferences: {
40 | nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION
41 | }
42 | })
43 |
44 | if (process.env.WEBPACK_DEV_SERVER_URL) {
45 |
46 | win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
47 | if (!process.env.IS_TEST) win.webContents.openDevTools()
48 | } else {
49 | createProtocol('app')
50 |
51 | win.loadURL('app://./index.html')
52 | }
53 |
54 | win.on('closed', () => {
55 | win = null
56 | })
57 | }
58 | ```
59 |
60 | O `win` será a nossa janela inicial, onde **BrowserWindow** é um componente do electron, e dentro das opções definimos a altura, largura e preferências da janela(no caso, a integração com o node para conseguirmos usar recursos internos, como o fs por exemplo).
61 |
62 | * As opções adicionais do BrowserWindow estão disponíveis [aqui](https://www.electronjs.org/docs/api/browser-window).
63 |
64 | A condição seguinte é relacionada ao modo desenvolvedor(ou não), carregando a URL de nosso html base que está em `./public/index.html`.
65 |
66 | * Podemos chamar o electron normalmente dentro do `` dos componentes do Vue e utilizar com os métodos, computed's normalmente, exemplo:
67 |
68 | ```js
69 | ...
70 |
76 | ```
77 |
78 | * o setup() significa a mesma coisa que o antigo hook `created()`, e podemos retornar o que queremos que o template tenha acesso.
79 |
80 | * Utilizamos o ref para criar uma referência do `count`, e retornamos o estado.
81 |
82 | * Diferente do Vue 2.x, não temos necessidade de utilizar o `this.**`.
83 |
84 | * Podemos mutar a variável diretamente pelo template, como: `@click="++count"`
85 |
86 | O setup recebe dois argumentos:
87 |
88 | ```js
89 | setup(props, context) {
90 | console.log(props);
91 | console.log(context);
92 | }
93 | ```
94 |
95 | Podemos também formar grupos de objetos com o `reactive`(anterior no Vue 2.x como Vue.observable)
96 |
97 | ```html
98 |
119 | ```
120 |
121 | ### Computed
122 |
123 | ```html
124 |
125 |
128 |
129 |
130 |
151 | ```
152 |
153 | ### toRefs
154 |
155 | Agora conseguimos criar componentes de formulário de uma forma melhorada, sem a necessidade de utilizar $emit por conta de termos a referência das variáveis.
156 |
157 | ```html
158 |
159 |
160 |
161 |
162 |
163 |
175 | ```
176 |
177 | ### watch
178 |
179 | Mantendo a sintaxe parecido com o Vue 2.x, o primeiro parâmetro é o que será escutado e o segundo um callback com a execução da lógica, recebendo o novo valor como parâmetro do callback:
180 |
181 | ```html
182 |
214 | ```
215 |
216 | ### watchEffect
217 |
218 | O watchEffect escuta todas as alterações que estão no estado reativo:
219 |
220 | ```html
221 |
222 |
225 |
226 |
227 |
252 | ```
253 |
254 | ### LifeCycleHooks
255 |
256 | Temos os mesmos life cycles, só que agora na API:
257 |
258 | ```html
259 |
282 | ```
283 |
284 | ### Nuxt
285 |
286 | O [Nuxt](https://nuxtjs.org/) introduzou o [módulo da API de Composição](https://composition-api.nuxtjs.org/), dessa forma conseguimos utilizar as novas features em nossos projetos:
287 |
288 | ```js
289 | // index.vue
290 | import { ref, defineComponent, useContext } from '@nuxtjs/composition-api'
291 |
292 | export default defineComponent({
293 | setup() {
294 | const item = ref({ foo: 'bar' });
295 | const { store } = useContext(); // implementação do Vuex
296 | store.dispatch('action', item.value);
297 | },
298 | })
299 | ```
300 |
301 | * Se quiser se aprofundar na API, recomendamos a [documentação](https://composition-api.vuejs.org/#summary).
302 |
303 | Na próxima seção iremos mostrar algumas mudanças para utilizar as lib's no Vue 3.x
304 |
305 | [Próxima Seção](./2%20-%20Ecossistema.md)
306 |
--------------------------------------------------------------------------------
/docs/tutorial/9 - Next/10 - IonicVue.md:
--------------------------------------------------------------------------------
1 | # Ionic Vue 3
2 |
3 | O [Ionic](https://ionicframework.com/docs/vue/overview) lançou uma versão compatível com o Vue 3, trazendo uma nova forma de criar aplicativos.
4 |
5 | ## Iniciando com Ionic Vue 3.x
6 |
7 | Primeiramente, precisamos instalar as dependência do Ionic:
8 |
9 | `yarn global add -g @ionic/cli@latest native-run cordova-res`
10 |
11 | ou
12 |
13 | `npm install -g @ionic/cli@latest native-run cordova-res`
14 |
15 | Para criar o nosso primeiro aplicatio, usamos:
16 |
17 | `ionic start heart-project tabs --type vue --capacitor`
18 |
19 | Devido ao [Capacitor](https://capacitorjs.com/), precisamos instalar os elementos para PWA:
20 |
21 | `yarn add install @ionic/pwa-elements`
22 |
23 | ou
24 |
25 | `npm install @ionic/pwa-elements`
26 |
27 | em nosso `main.ts`, adicionamos:
28 |
29 | ```ts
30 | import { defineCustomElements } from '@ionic/pwa-elements/loader';
31 |
32 | defineCustomElements(window);
33 | ```
34 |
35 | Agora só precisamos rodar:
36 |
37 | `ionic serve`
38 |
39 | * Plugins externos do Ionic funcionam da mesma forma com o Vue 3.x
40 |
41 | [Próxima Seção](./11%20-%20Obrigado.md)
42 |
--------------------------------------------------------------------------------
/docs/tutorial/9 - Next/11 - Obrigado.md:
--------------------------------------------------------------------------------
1 | # Obrigado
2 |
3 | Muito obrigado por concluir o curso! Com todo o conteúdo passado você tem muitas alternativas para aprimorar seu conhecimento utilizado **Vue 3.x**!
4 |
5 | Em caso de dúvidas ou sugestões, contate diretamente pelo discorda da [He4rt](discord.io/He4rt) ou pelo criadores:
6 |
7 | Giovane Cardoso - [Twitter](https://twitter.com/NovoutT) - novout@hotmail.com
8 |
9 | [Projeto final](https://github.com/Novout/vue4noobs-projeto)
10 |
11 | [Repositório atual](https://github.com/Novout/vue4noobs)
12 |
--------------------------------------------------------------------------------
/docs/tutorial/9 - Next/2 - Ecossistema.md:
--------------------------------------------------------------------------------
1 | # Ecossistema
2 |
3 | Vamos demonstrar as mudanças que ocorreram nas novas versões do Vue-Router e Vuex!
4 |
5 | ## Vue-Router
6 |
7 | Tivemos uma mudança na estrutura de base no novo [VueRouter](https://github.com/vuejs/vue-router-next) para utilizar a base:
8 |
9 | ```js
10 | import { createRouter, createWebHistory } from "vue-router";
11 |
12 | const routes = [
13 | {
14 | path: "/",
15 | name: "Home",
16 | component: () => import("@/views/Home.vue")
17 | }
18 | ];
19 |
20 | const router = createRouter({
21 | history: createWebHistory(process.env.BASE_URL),
22 | routes
23 | });
24 |
25 | export default router;
26 | ```
27 |
28 | * Utilizamos `createRouter` e passamos um objeto com opções, no caso agora o `history` precisamos passar `createWebHistory` para utilizarmos o modo `history`. Temos outras opções como `createHashHistory` para usar no modo hash ou o `createMemoryHistory` para SSR.
29 |
30 | * Se estiver utilizando ``, necessita esperar o router ficar pronto para criar a instância. Utilize `router.isReady().then(() => app.mount('#app'))` por exemplo.
31 |
32 | Temos o `useRouter` para conseguirmos utilizar as coisas do router no setup:
33 |
34 | ```js
35 | import { useRouter } from 'vue-next-router';
36 |
37 | setup() {
38 | const router = useRouter();
39 |
40 | router.push({ name: 'he4rt' }));
41 | }
42 | ```
43 |
44 | Podemos agora criar rotas nos próprios componentes, por mais que seja um uso bem específico é uma adição muito válida:
45 |
46 | ```js
47 | import { defineComponent } from 'vue';
48 | import { useRouter } from 'vue-next-router';
49 |
50 | export default defineComponent({
51 | setup() {
52 | const router = useRouter();
53 |
54 | const createRoute = id => {
55 | router.addRoute({
56 | path: `/he4rt/${id}`,
57 | name: `he4rt-${id}`,
58 | component: () => import('@/views/He4rt.vue');
59 | });
60 | }
61 |
62 | return { createRoute }
63 | }
64 | });
65 | ```
66 |
67 | As guardas de rota tiveram uma mudança em seu retorno, agora retornam o valor primeiramente do que o `next()`. No exemplo abaixo, podemos determinar se a rota será renderizada ou não apenas pelo retorno do booleano:
68 |
69 | ```js
70 | router.beforeEach(() => booleanAuthenticated);
71 | ```
72 |
73 | ### Vuex
74 |
75 | O [Vuex 4](https://github.com/vuejs/vuex) trouxe algumas novas adições:
76 |
77 | Agora podemos utilizar o `createStore` para a loja:
78 |
79 | ```js
80 | import { createStore } from "vuex";
81 |
82 | export const store = createStore({
83 | state: {},
84 | mutations: {},
85 | actions: {}
86 | });
87 | ```
88 |
89 | Com o logger podemos com facilidade encontrar problemas no fluxo:
90 |
91 | ```js
92 | import { createLogger } from 'vuex';
93 |
94 | export const store = createStore({
95 | state: {},
96 | mutations: {},
97 | actions: {},
98 | plugins: [
99 | createLogger()
100 | ]
101 | });
102 | ```
103 |
104 | [Próxima Seção](./3%20-%20Hooks.md)
105 |
--------------------------------------------------------------------------------
/docs/tutorial/9 - Next/3 - Hooks.md:
--------------------------------------------------------------------------------
1 | # Hooks
2 |
3 | Os Hooks que já tiveram uma participação no Vue 2.x e agora devido a nova composição da API sendo integrado diretamente, é uma forma de reaproveitar código, substituindo os antigos mixins.
4 |
5 | Inspirado nos Hooks do React.js, todas as lib's compatíveis com o Vue 3.x veem com a mesma base padronização a utilizar de bibliotecas.
6 |
7 | Já mostramos os hooks padrões, como a nova forma de utilizar os `LifeCycleHooks`, mas agora também podemos criar os nossos próprios.
8 |
9 | ## Nova Sintaxe
10 |
11 | Diferente do Vue 2.x em que utilizamos o `this.*` para acessar os plugins internos, agora nos importamos separadamente e instânciamos o que queremos:
12 |
13 | ```js
14 | import { defineComponent, onBeforeDestroy } from 'vue';
15 | import { useRouter } from 'vue-router-next';
16 |
17 | export default defineComponent({
18 | setup() {
19 | const router = useRouter(); // instanciação do router
20 |
21 | onBeforeDestroy(() => { // life cycle hook
22 | router.push('/');
23 | })
24 |
25 | return { router } // acessível ao template
26 | }
27 | })
28 | ```
29 |
30 | * Além de utilizaremos apenas o que precisamos, a grande vantagem de utilizar hook's é que podemos criar a nossa lógica de forma separada, sem ser dependente do template.
31 |
32 | ## Hooks Próprios
33 |
34 | Podemos separar por arquivos a nossa lógica, assim conseguindo criar uma estrutura interessante nos nossos projetos:
35 |
36 | ```js
37 | // './src/use/state.js'
38 | import { reactive } from 'vue';
39 |
40 | export const useState = () => {
41 | const state = reactive({
42 | value: 0
43 | });
44 |
45 | // convertendo para uma referência
46 | return toRefs(state)
47 | }
48 | // ./src/pages/home.vue
49 | import { useState } from '@/use/state';
50 |
51 | export default {
52 | setup() {
53 | // Diferente de desconstruir uma prop, aqui não perdemos a referência, já que estamos retornando com toRefs(...)
54 | const { value } = useState();
55 |
56 | return { value }
57 | }
58 | }
59 | ```
60 |
61 | * Uma grande vantagem dos hook's é que o nosso código fica menos poluido do que utilizar `this.*` sempre que queremos acessar um prototype.
62 |
63 | * Em hook's assíncronos, recomendamos que tenha cuidado pois o componente não vai ser criado até a instância do setup() ser retornada, ou seja, se a promise não retornar, o componente vai ficar eternamente carregando.
64 |
65 | * Podemos criar arquivos de hook's extensos e com qualquer recurso que o vue nos disponibiliza:
66 |
67 | ```ts
68 | import { ref, reactive, UnwrapRef } from 'vue';
69 |
70 | // Simulando React hook utilizando a Api de Composição do Vue em Typescript
71 |
72 | const useStateObject = (entryObj: T) => {
73 | const obj = reactive(entryObj); // criando o objeto reativo
74 | const set = (valueObj: T) => { // percorrendo todas as chaves da tupla para mutar uma por uma
75 | Object.entries(valueObj).forEach(([key, val]) => {
76 | obj[key] = val;
77 | });
78 | };
79 |
80 | return [obj, set];
81 | }
82 |
83 |
84 | export const useState = (entryValue: T) => {
85 | if (typeof entryValue === 'object') { // se for um objeto, iremos utilizar outra lógica
86 | return useStateObject(entryValue);
87 | }
88 | const state = ref(entryValue); // referência criada
89 | const set = (value: T) => { // mutando a referência
90 | state.value = value as UnwrapRef;
91 | };
92 |
93 | return [state, set];
94 | };
95 | ```
96 |
97 | ```ts
98 |
99 |
100 |
101 |
102 |
115 | ```
116 |
117 | * Não é um exemplo útil na prática, já que podemos mutar o `count` diretamente pelo template, sem a necessidade do `setCount`, usamos apenas para fins didáticos.
118 |
119 | ## VueUse
120 |
121 | Recentemente atuailizado para uma versão compatível com o Vue 3.x, temos uma gama de hook's já prontos para utilizar em nosso projeto com o [VueUse](https://github.com/antfu/vueuse)
122 |
123 | ```js
124 | import { useMouse } from '@vueuse/core';
125 |
126 | setup() {
127 | const { x, y } = useMouse(); // posição do cursor
128 |
129 | return { x, y }
130 | }
131 | ```
132 |
133 | * Recomendamos fortemente que dê uma olhada nesta lib, pois possui muitos recursos comuns e que podem te "salvar" em um futuro projeto.
134 |
135 | [Próxima Seção](./4%20-%20Suspense.md)
136 |
--------------------------------------------------------------------------------
/docs/tutorial/9 - Next/4 - Suspense.md:
--------------------------------------------------------------------------------
1 | # Suspense
2 |
3 | Suspense é um recurso utilizado no React.js, sendo um recurso especial assim como o `transition` e `transition-group`, seu objetivo é ser um watcher do componente e ter as informações de carregamento. Por mais que podemos monitorar a criação de um componente pelo retorno do setup() sem a necessidade de recursos adicionais, o Suspense vem para utilizar isso de uma forma elegante e que facilite para os desenvolvedores.
4 |
5 | Até o momento(17/12/2020), o recurso está em fase beta e não é recomendável para projetos finais.
6 |
7 | ## Utilização
8 |
9 | ```html
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | ```
21 |
22 | * De uma forma simples, o #default é o componente que será escutado e esperado em sua construção(finalização do hook onMounted), enquanto o #fallback é o componente que será carregado enquanto o `ComponenteEsperado` está sendo criado.
23 |
24 | * Se o componente esperado executar um erro, podemos capturar e tratar este erro:
25 |
26 | ```html
27 |
38 | ```
39 |
40 | * Lembrando que este erro retornado é genérico, tendo a necessidade de tratar o erro de alguma forma. Como a promise irá ficar infinitamente carregando, recomendamos utilizar o v-if/v-else com um erroHandler para conseguir exibir o erro sem que a promise continue a ser carregada.
41 |
42 | [Próxima Seção](./5%20-%20JSX.md)
43 |
--------------------------------------------------------------------------------
/docs/tutorial/9 - Next/5 - JSX.md:
--------------------------------------------------------------------------------
1 | # JSX
2 |
3 | Um recurso que já existia no Vue 2.x, agora podemos de uma forma mais complementada em utilizar o tão famoso [JSX](https://github.com/vuejs/jsx-next), onde instânciamos um `defineComponent` e executamos o template dentro do próprio componente.
4 |
5 | ## Instalação
6 |
7 | Execute o comando:
8 |
9 | `npm install @vue/babel-plugin-jsx -D`
10 |
11 | e no seu .babelrc na raíz do projeto:
12 |
13 | ```jsx
14 | {
15 | "plugins": ["@vue/babel-plugin-jsx"]
16 | }
17 | ```
18 |
19 | * Também podemos utilizar o JSX com Typescript(TSX)
20 |
21 | Exemplo básico:
22 |
23 | ```jsx
24 | import { defineComponent } from "vue";
25 |
26 | export default defineComponent({
27 | name: "App",
28 | render() {
29 | return (
30 | <>
31 |
32 | >
33 | )
34 | }
35 | });
36 | ```
37 |
38 | Podemos utilizar diretamente pelo retorno do setup():
39 |
40 | ```jsx
41 | import { defineComponent } from "vue";
42 |
43 | export default defineComponent({
44 | name: "App",
45 | setup() {
46 | return () => (
47 | <>
48 |
49 | >
50 | )
51 | }
52 | });
53 | ```
54 |
55 | ## Diretivas e Modificadores
56 |
57 | Podemos utilizar diretamente pelo retorno do setup():
58 |
59 | ```jsx
60 | import { ref, defineComponent } from "vue";
61 |
62 | export default defineComponent({
63 | name: "App",
64 | setup() {
65 | let show = ref(false);
66 |
67 | const toggleBestGroup = () => show.value = !show.value;
68 |
69 | return () => (
70 | <>
71 |
72 | Olá He4rt!
73 | >
74 | )
75 | }
76 | });
77 | ```
78 |
79 | * Utilizando o V-Model:
80 |
81 | ```jsx
82 | import { ref, defineComponent } from "vue";
83 |
84 | export default defineComponent({
85 | name: "App",
86 | setup() {
87 | let text = ref("");
88 |
89 | return () => (
90 | <>
91 |
92 | {text}
93 | >
94 | )
95 | }
96 | });
97 | ```
98 |
99 | ## Usando Componentes
100 |
101 | Não precisamos importar os componentes com `components: {...}`, podendo utilizar diretamente:
102 |
103 | ```jsx
104 | import { ref, defineComponent } from "vue";
105 | //...
106 | const Header = defineComponent({...});
107 | //...
108 | const Content = defineComponent({...});
109 | //...
110 | export default defineComponent({
111 | name: "App",
112 | setup() {
113 | return () => (
114 | <>
115 |
116 |
117 | >
118 | )
119 | }
120 | });
121 | ```
122 |
123 | [Próxima Seção](./6%20-%20Typescript.md)
124 |
--------------------------------------------------------------------------------
/docs/tutorial/9 - Next/6 - Typescript.md:
--------------------------------------------------------------------------------
1 | # Typescript
2 |
3 | Uma dos pontos bastante criticados do Vue 2.x é a falta de suporte direto ao Typescript, onde a utilização de classes com `vuex-class-modules` e `vue-class-components` era necessária, agora temos opções adicionais, principalmente devido ao Vue 3.x ser escrito no próprio Typescript.
4 |
5 | ## Configuração
6 |
7 | Se estiver utilizando o Vue-CLI, utilizamos o comando `vue add typescript` em um projeto já existente, e agora podemos utilizar como `