Olá! Bem-vindo a mais um curso da Formação Angular aqui na Alura. Meu nome é Rafael Paiva de Oliveira e serei o seu instrutor neste curso.
Audiodescrição: Rafael é uma pessoa de pele clara, usa óculos, tem cabelo muito curto e castanho, com entradas no cabelo e barba um pouco grisalha. Ele veste uma camiseta marrom clara e, ao fundo, há uma iluminação azul com alguns livros e enfeites na estante.
Se no curso anterior demos os primeiros passos no framework, agora vamos nos aprofundar e falar mais sobre como escalar nossa aplicação, principalmente sobre a comunicação entre componentes pai e filho, usando @Input e @Output, que são a nova forma de comunicação utilizando o que há de mais moderno no framework hoje, que é o signal. É totalmente reativo, então vamos aprender a nova forma de comunicação dessa maneira.
Além disso, temos aquele problema clássico de como compartilhar nosso estado e informações entre telas, e para isso também aprenderemos a usar serviços e a injetá-los por meio de injeção de dependências. Também trabalharemos com rotas de forma profissional, atribuindo qual página vai em cada rota e permitindo que o Angular Router capture as propriedades e os parâmetros de rota. Com isso, conseguimos que a aplicação recarregue entre uma página e outra apenas os dados necessários, sem recarregar toda a página.
Com isso, temos a chamada Single Page Application (aplicação de página única), que é muito mais moderna e fluida para a pessoa usuária, pois não é necessário solicitar ao servidor a página a cada navegação. Assim, há também uma navegação inteligente.
Para colocar tudo isso em prática, vamos usar o UseDev, um projeto que estamos apresentando como uma solução completa. Teremos aqui um catálogo de produtos para escolher; por exemplo, ao clicar em um produto, veremos o detalhe do produto. Poderemos adicioná-lo ao carrinho e, ao clicar no ícone do carrinho, teremos a página do carrinho, podendo resumir as informações, verificar quais produtos foram adicionados, aumentar ou reduzir quantidades, calcular automaticamente os valores e eliminar produtos. Tudo isso será feito usando rotas e componentes.
Aprenderemos a usar componentes mais focados na reutilização, mais genéricos e de apresentação, e como separar esses componentes em componentes inteligentes, aplicando o conceito de Atomic Design (design atômico). Para aproveitar bem este curso, é recomendado que tenhamos conhecimentos de HTML, CSS e JavaScript, além de saber o básico para criar uma aplicação Angular, conforme vimos no curso anterior.
Estamos muito entusiasmados para aprender juntos e dar este passo adiante em nossos estudos de Angular. Vamos começar? Pegue seu café, abra o VSCode e vamos lá!
Vamos começar a desenvolver nossa aplicação. Já visualizamos o projeto no Figma, agora vamos implementá-lo. Estamos com o VS Code aberto e na pasta do projeto UseDev. Se já passamos pela etapa de "Preparando o Ambiente" e clonamos o projeto, vamos explorar um pouco a estrutura de pastas.
O projeto é inicial e vem com um "Hello World". A única adição feita foi preparar o projeto para nós. Após clonar o projeto, devemos executar npm install para criar a pasta node_modules.
npm install
Existe uma ramificação chamada projeto-inicial, então vamos acessá-la com git checkout projeto-inicial.
git checkout projeto-inicial
Dentro dessa ramificação, já existem alguns arquivos iniciais para facilitar nosso desenvolvimento. Na pasta "public/images", há várias imagens que utilizaremos para desenvolver nossa interface, como o logo e a foto do produto. Também temos um arquivo com uma lista de produtos para trabalharmos e o style.css, que é o arquivo global. Ele já possui a fonte importada que usaremos e algumas classes prontas para agilizar o desenvolvimento do CSS.
Primeiro, vamos verificar a versão do Node que estamos usando com node -v. Estamos utilizando a versão 22.12, e o Angular que usaremos é a versão mais recente, a 21. Na documentação do Angular, há uma tabela de compatibilidade. Como desenvolveremos o projeto usando o Angular 21, se estivermos usando o Node 20, deve ser pelo menos a versão 20.19. Como estamos na versão 22, deve ser pelo menos a 22.12. Se tivermos uma versão superior, como a 22.18, não há problema. Vamos também verificar a versão do Angular instalada: estamos na versão 21.
Para instalar a ferramenta de linha de comando Angular CLI, usamos npm install -g @angular/cli.
npm install -g @angular/cli
Essa ferramenta é uma interface de linha de comando, então tudo que desenvolveremos — criar um novo projeto, criar um componente — será feito pelo terminal.
Vamos colocar o projeto para rodar com npm start. No package.json, além das dependências, temos os scripts que executaremos, como npm start ou ng serve, que abrirá no porto 4200. Vamos executá-lo.
npm start
A tela inicial apresenta o "Hello World", como quando criamos um projeto novo.
Já visualizamos as telas que desenvolveremos. Neste vídeo, vamos desenvolver a primeira tela, que é a lista de produtos, a tela inicial do site. Alguns elementos se repetem, como o cabeçalho e o banner. Vamos usar o banner mais simples e não desenvolveremos a aplicação 100% agora, pois o foco é desenvolver a tela com os elementos que usaremos durante a aula. Se algum elemento não for desenvolvido agora e precisarmos dele mais tarde, podemos adicioná-lo depois.
No cabeçalho, faremos algo mais simples: apenas o logo e o carrinho de compras. Abaixo, desenvolveremos a lista de produtos, as "promoções especiais" e o rodapé em preto, com o logo verde, mas sem os demais itens que não são necessários. Tentaremos seguir o layout, mas simplificá-lo para se ajustar ao contexto que vamos desenvolver.
Vamos começar. No Angular, sempre temos o main, que inicializa a primeira aplicação. Todo projeto em Angular tem um primeiro componente, que é o app, carregado no index, e possui a parte de TypeScript, HTML e CSS. Vamos ao HTML, clicar ao lado e apagar o conteúdo. Salvamos com "Ctrl+S" e verificamos: o Angular já possui hot reload, então, cada vez que salvamos, a tela é atualizada. Agora está em branco.
Precisamos criar quatro partes: o cabeçalho, o banner, a lista de produtos (parte principal, corpo da página) e o rodapé. Vamos começar desenvolvendo o HTML. Colocaremos as etiquetas header, e dentro do header colocaremos o logo: image source.
<header>
<img src="images/logo.svg" alt="Logo UseDev" />
</header>
Agora, vamos adicionar o carrinho. O carrinho tem um detalhe: colocaremos uma div ao redor do carrinho, chamaremos essa div de cart, pois não será apenas a imagem do carrinho.
<div class="cart">
<img src="images/shopping_cart.svg" alt="ícone carrinho de compras"/>
<span class="badge">0</span>
</div>
Deixaremos o main, que será a parte principal, e o footer, além da imagem do banner que está na pasta images/banner.png.
<main></main>
<footer></footer>
<img src="images/banner.png" class="banner" alt="Imagem banner" />
Vamos revisar novamente. Agora já estamos posicionando os elementos. O reset.css que fiz, que é este inicial, vou comentar apenas para mostrar que todos os navegadores têm alguns valores CSS por padrão, e isso varia de navegador para navegador. Queremos que a pessoa que use nosso site tenha uma experiência consistente em qualquer navegador. Neste caso, ao inspecionar o elemento, percebemos que é o body que tem margem. O Chrome coloca uma margem no body que não queremos, aquela margem branca. Queremos que ocupe 100%, por isso usamos a estratégia de aplicar estilos a todos os elementos — por isso o asterisco — e gostamos de fazer esse reset.
No mais, não há muito mistério: no container usamos display:flex para alinhar verticalmente ao centro, e horizontalmente queremos colocar um em cada lado. Já deixamos algumas coisas adiantadas. Aqui, o banner; aquele span, aquele badge, é porque queremos que, à medida que desenvolvemos a aplicação, elementos sejam adicionados ao carrinho, mostrando esse número acima do carrinho. Assim, já deixamos pronto. Estamos fazendo toda a parte estática; apenas desenhando os elementos na tela, ainda não terá funcionalidade. Depois, começaremos a parte dinâmica para fazer com que as coisas funcionem.
O footer, o banner já temos, o logo também; acima temos o header, e agora falta o logo no footer, então vamos lá. Continuando, vamos colocar a imagem; é bastante parecida com a do footer, mas a diferença é que há um logo alternativo, que é verde, para dar melhor contraste com o preto, que é esta cor; logo verde. Colocamos o logo "os devs" em verde, e tem um pequeno texto que chamaremos de slogan; criamos uma classe chamada slogan, que é este texto.
<div class="container">
<img src="images/logo-green.svg" alt="Logo UseDev Verde" />
<div class="slogan">Hora de abraçar seu lado geek!</div>
</div>
Dessa forma, com o CSS que já preparamos para adiantar, também fica bastante responsivo para dispositivos móveis, o que nos ajudará a não precisar focar tanto em desenvolver a tela — o HTML e CSS — e sim focar na parte do curso, que é falar sobre componentização. Vamos criar este ambiente, depois trabalharemos sobre ele e o modificaremos. Só falta a parte principal, a do meio, então vamos lá. Esta parte tem um pequeno título, que acreditamos ser um H2, e depois uma lista onde usaremos um grid para posicionar, e então cada card terá a parte da imagem e a parte da informação com um resumo abaixo. Vamos lá.
Dentro do main, vamos criar um H2; colocaremos "promos especiais", já está ficando com a fonte correta porque já fizemos o CSS.
<div class="container">
<h2>Promos especiais</h2>
<div class="product-list">
<div class="product-card">
<img class="product-image" src="images/product-capy.png" alt="Foto do produto Camiseta Capy"/>
<div class="product-info">
<div class="product-name">Camiseta Capy</div>
<div class="product-price">R$ 28</div>
</div>
</div>
</div>
</div>
Se quisermos testar como seria com outro card, se respeita o grid; então copiaremos 2, 3, 4, se copiarmos 4 vezes fica em 4 colunas; se colocarmos mais um, começará a descer para a próxima linha, igual no Figma; por quê? Aqui nos estilos temos nosso ProductList; está usando display:grid, então também tem isso; inclusive configuramos para telas pequenas, móveis, em telas pequenas está em 2 colunas; vejamos como fica em dispositivos móveis. Vamos inspecionar: abrir o F12, clicar com o botão direito, inspecionar, clicaremos na vista para ver como fica em celular; aqui deixamos apenas um, acreditamos que a visualização em móvel ficaria melhor, mas também fizemos certa responsividade, tudo isso já está pronto no CSS; se a tela for um pouco menor, um tablet, enfim, se ajustará ao conteúdo.
Então já temos uma base; como podemos ver todos os produtos? Lembram que comentamos que na pasta "src/app" há um arquivo chamado product.ts? Ele tem uma lista de produtos exportada com todos esses produtos para facilitar nossa vida. E também está o tipo; então criamos o tipo com name, description, price, como podemos fazer isso aqui?
export type Product = {
id: number;
name: string;
description: string;
price: number;
imageUrl: string;
}
export const products: Product[] = [
{
id: 1,
name: 'Camiseta Capy',
description: 'Camiseta estampada com design exclusivo de capivara.',
price: 25,
imageUrl: 'images/product-capy.png',
},
]
Vamos colocá-lo rapidamente em app.ts, que é o arquivo TypeScript, vamos criar um Product aqui, uma variável do tipo Signal, criaremos um Signal para controlar o estado; diremos que é do tipo Array de produtos, e o inicializaremos com o valor desse arquivo de produtos que criamos.
import { Product, products } from './product';
export class App {
products = signal<Product[]>(products);
}
E aqui podemos fazer um for, por exemplo; em vez de ter vários cards, podemos deixar apenas um e colocar um for ao redor.
@for (product of products(); track product.id) {
<div class="product-card">
<img class="product-image" [src]="product.imageUrl" alt="Foto do produto Camiseta Capy"/>
<div class="product-info">
<div class="product-name">{{ product.name }}</div>
<div class="product-price">R$ {{ product.price }}</div>
</div>
</div>
}
Agora temos oito produtos, e como faríamos para mudar a quantidade de artigos no carrinho? Se clicarmos para fazer um teste... vamos lá, vamos criar um método aqui, click: vamos ouvir o clique e criar um método chamado addToCart.
addToCart() {
this.totalCartItems.update(value => value + 1);
}
Em nosso TS criaremos essa função addToCart, que quer adicionar algo ao carrinho, e o que faremos é criar outro signal para controlar o estado, chamaremos de totalCartItems; diremos que é um signal que começa em zero, e sempre que clicarmos nesse botão, sempre aumentaremos (update), então teremos um valor aqui e somaremos um, somaremos um; com isso podemos colocar essa variável no badge acima.
totalCartItems = signal(0);
E agora se clicarmos, está sendo adicionado ao carrinho; então, temos como criar a variável e controlá-la; podemos colocar até um if aqui também, e se não houver totalCartItems não queremos mostrar; só se existir, porque quando for zero não mostraremos nada.
@if (totalCartItems() > 0) {
<span class="badge">{{ totalCartItems() }}</span>
}
Dessa forma, conseguimos criar a base da nossa aplicação e já temos a funcionalidade de adicionar produtos ao carrinho. No próximo vídeo, começaremos a dividir e criar os componentes, separá-los dentro da página. Nos vemos lá. Até mais!
Seguimos com nossos estudos. No último vídeo, criamos nosso header, a parte principal (main) e o footer, conforme o design da primeira página. Estamos desenvolvendo tudo de forma separada e organizada, utilizando as etiquetas semânticas do HTML. No entanto, estamos desenvolvendo tudo isso em um único componente.
No Angular, sempre há um componente que é criado primeiro, chamado app-root. Esse componente, na verdade, não existe como um elemento HTML; é um elemento criado pelo Angular. O Angular já cria esse componente para nós, e ele possui alguns valores. Basicamente, é uma classe em TypeScript com um decorator @Component que contém algumas metainformações.
O componente possui um selector, que é como o Angular entende que, ao ver a etiqueta app-root, sabe que esse elemento HTML não existe, mas buscará um elemento pelo prefixo. Sempre queremos que os elementos que criamos venham com esse prefixo app. Podemos alterar isso, mas esse é o padrão. Além disso, o componente pode importar outros componentes.
Por padrão, estamos usando HTML e CSS em arquivos separados. Tanto a parte do template quanto a parte do estilo são passadas para o componente, que então sabe onde está o template e pode se comunicar. Temos aqui os sinais de lista de produto e total de itens do carrinho, que estão fazendo o bind no HTML. Também criamos um evento apenas para teste. Quando esse evento ocorre no HTML, o eventBind chama o método test.
Embora esses arquivos estejam separados, eles formam um único componente. Na prática, dificilmente, a menos que estejamos desenvolvendo uma única página ou uma calculadora, trabalhamos com um único componente. Em uma aplicação real, que é bastante grande, começamos apenas com uma tela, que nem está funcionando 100%, e já temos uma quantidade significativa de linhas de código. Imagine criar todo o site em um único componente; seria difícil de manter no futuro. Não faz muito sentido.
Facilita ter eventos e variáveis em um único lugar, mas isso impede que a aplicação cresça de forma adequada. Com 5 ou 6 telas, teremos elementos que queremos reutilizar. No caso, tivemos que fazer "Ctrl+C", "Ctrl+V" e acabamos usando o *ngFor. Na prática, precisamos usar o poder do Angular, que é o framework que possui o conceito de criar componentes. Não precisamos usar apenas o componente criado inicialmente; podemos criar nossos próprios componentes, o que proporciona uma certa organização, pois cada componente terá um foco.
Por exemplo, o cabeçalho será um componente, o banner será outro componente. Assim, ao clicar no index, sabemos que dentro do banner temos nosso app-root. Quando entramos no app.component, apenas olhando o HTML, já sabemos mais ou menos quais componentes o app.component precisa carregar, mesmo sem conhecer os detalhes. Se quisermos saber os detalhes de um componente específico, podemos entrar nele e fazer a manutenção.
Quando temos muitas coisas desordenadas, encontrar onde devemos dar manutenção se torna mais complicado. Da mesma forma, abordamos a parte de compatibilidade. Alguma dúvida? A documentação do Angular é muito rica e atualizada. Na documentação, encontramos o CLI, que é o Command Line Interface (Interface de Linha de Comando).
Ao trabalhar com Angular, instalamos com npm install -g @angular/cli. A partir daí, obtemos o comando ng. Para criar um novo projeto, utilizamos ng new, o que ajuda bastante. Quando vamos criar um novo componente, poderíamos simplesmente copiar e colar arquivos manualmente, mas isso consumiria muito tempo. Além do ng new para criar um novo projeto, temos o ng generate, que usaremos para criar componentes e serviços nos próximos vídeos.
Podemos usar ng generate ou sua abreviação ng g para criar várias coisas. Para criar componentes, usamos ng generate component ou ng g c. Vamos criar quatro componentes, representando cada parte da nossa aplicação. Primeiro, vamos parar a aplicação, limpar o terminal e executar ng generate component.
ng generate component
Se começarmos a criar componentes, eles ficarão soltos na pasta app. Queremos criar uma pasta de components para organizar melhor. Podemos criar diretamente components/header, por exemplo. Se passarmos a rota desejada com o nome, ele criará a pasta components, se não existir, e o header dentro dela.
ng generate component components/header
Se esquecermos de especificar component, podemos criar o footer para testar e usar a abreviação ng generate component para criar o footer.
ng g c footer
Vamos criar a parte principal da estrutura, chamada product-list. Se esquecermos de colocar dentro de components, podemos mover depois.
ng g c product-list
O padrão do Angular é criar a pasta e nomear os arquivos com hífen, enquanto a classe usa o padrão PascalCase, com a primeira letra maiúscula. Vamos criar o último componente, o banner, com ng generate component components/banner.
ng g c components/banner
Cada componente criado tem seu próprio seletor, como app-header. Para usá-lo, copiamos o seletor e o adicionamos no HTML do app component.
<app-header></app-header>
Angular recomenda usar o self-closing (auto-fechamento) para componentes.
<app-header />
Se der erro, é porque o Angular não reconhece o seletor como um elemento HTML normal. Precisamos importar o componente no app.ts, onde estão os imports.
import { Header } from './components/header/header';
Após importar, o Angular reconhecerá o componente.
Quando criamos um arquivo CSS, ele tem um escopo próprio. Podemos mover estilos específicos para dentro do componente correspondente, garantindo que não haja colisão de nomes. Isso encapsula o estilo dentro do componente, evitando conflitos.
Vamos remover o footer do app HTML e adicionar app-footer. Podemos importar diretamente o footer no arquivo. Agora, o footer está funcionando. Precisamos colocar o código HTML dentro do footer e mover seu estilo correspondente.
<app-footer />
Estamos organizando a aplicação desde o início, observando padrões de layout que fazem sentido dividir em componentes. Isso facilita a reutilização e manutenção. Quando criamos um componente, ele pode importar outros componentes, como um lego.
Vamos mover o estilo do banner para seu arquivo CSS correspondente. O mesmo faremos com o product-list, movendo o CSS e a lista de produtos para o componente responsável. O app não precisa saber o que há dentro do product-list, apenas importa os componentes necessários.
No index.html, o app-root inicia a aplicação, importando componentes como header, banner, product-list e footer.
<app-header />
<app-banner />
<app-product-list />
<app-footer />
Essa organização faz sentido e facilita a manutenção.
Na próxima aula, trabalharemos mais sobre como um componente pode ter outro componente, criando um product-card mais reutilizável. Vamos praticar juntos como criar melhores componentes e organizar melhor nossa aplicação. Nos vemos na próxima aula!
O curso Angular: signals, services e router possui 299 minutos de vídeos, em um total de 45 atividades. Gostou? Conheça nossos outros cursos de Angular em Front-end, ou leia nossos artigos de Front-end.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
O Plano Plus evoluiu: agora com Luri para impulsionar sua carreira com os melhores cursos e acesso à maior comunidade tech.
2 anos de Alura
Matricule-se no plano PLUS 24 e garanta:
Jornada de estudos progressiva que te guia desde os fundamentos até a atuação prática. Você acompanha sua evolução, entende os próximos passos e se aprofunda nos conteúdos com quem é referência no mercado.
Back-end, Dados, Front-end, DevOps, Mobile, Gestão & Negócios, UX & Design, Cibersegurança, Cloud, Inteligência Artificial
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
Acesso à inteligência artificial da Alura.
No Discord, você participa de eventos exclusivos, pode tirar dúvidas em estudos colaborativos e ainda conta com mentorias em grupo com especialistas de diversas áreas.
Catálogo de tecnologia para quem é da área de Marketing
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
20% de desconto na Pós Tech
Luri Vision chegou no Plano Pro: a IA da Alura que enxerga suas dúvidas, acelera seu aprendizado e conta também com o Alura Língua que prepara você para competir no mercado internacional.
2 anos de Alura
Todos os benefícios do PLUS 24 e mais vantagens exclusivas:
Acesso ao catálogo da Casa do Código e leitura dentro da plataforma
Chat, busca, exercícios abertos, revisão de aula, geração de legenda para certificado.
Modo entrevista - Pratique situações reais e evolua com feedback personalizado
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Para quem quer atingir seus objetivos mais rápido: Luri Vision ilimitado, vagas de emprego exclusivas e mentorias para acelerar cada etapa da jornada.
2 anos de Alura
Todos os benefícios do PRO 24 e mais vantagens exclusivas:
Lives CareerUp: eventos exclusivos com foco em empregabilidade e carreira
Mentorias de carreira: 2 encontros individuais com mentores do Talent Lab
Conecte-se ao mercado com mentoria individual personalizada, vagas exclusivas e networking estratégico que impulsionam sua carreira tech para o próximo nível.