ViewChild no Angular: Aprenda a acessar elementos filhos com facilidade
Aprenda a interagir com elementos filhos no Angular usando ViewChild. Ele permite manipular elementos do DOM e componentes filhos.

O uso do ViewChild no Angular permite uma interação programática com os elementos da tela, permitindo a manipulação de propriedades, eventos e métodos desses elementos dentro do componente Angular. Essa funcionalidade é particularmente útil para realizar diversas tarefas, tais como acesso ao DOM (Document Object Model), modificação dinâmica de elementos HTML e integração com bibliotecas externas.
Neste artigo, discutiremos detalhadamente o seu uso e forneceremos um exemplo prático para ilustrar seu funcionamento em um cenário real. Além disso, abordaremos a última novidade da versão 17.2: o viewChild
(não ViewChild
), uma variação que utiliza o signal. Vale ressaltar que esta funcionalidade ainda está em developer preview.
Uso básico do ViewChild
Quando utilizamos o decorador @ViewChild("el")
, o Angular realizará uma busca dentro do HTML para identificar o primeiro elemento marcado com #el
. Veja no exemplo a seguir:
import { Component, ElementRef, ViewChild } from "@angular/core";
@Component({
selector: "app-exemplo1",
standalone: true,
template: `
<div #el>Olá sou o exemplo 1</div>
<button (click)="testar()">Testar</button>
`,
})
export class Exemplo1Component {
@ViewChild("el") divElement!: ElementRef<HTMLDivElement>;
testar() {
console.log(`Div encontrado: ${!!this.divElement}`);
}
}

É um processo bem simples e dinâmico, tanto que caso o elemento procurado não esteja na tela em um dado momento, o Angular atualiza o valor de forma automática, ou seja, a pesquisa é dinâmica:
import { Component, ElementRef, ViewChild } from "@angular/core";
@Component({
selector: "app-exemplo2",
standalone: true,
template: `
@if (mostrarDiv) {
<div #el>Olá sou o exemplo 1</div>
}
<button (click)="testar()">Testar</button>
<button (click)="mostrarDiv = !mostrarDiv">Mostrar/Esconder Div</button>
`,
})
export class Exemplo2Component {
mostrarDiv = true;
@ViewChild("el") divElement!: ElementRef<HTMLDivElement>;
testar() {
console.log(`Div encontrado: ${!!this.divElement}`);
}
}

Aplicando o foco em um input
Um exemplo bastante comum em que costumo utilizar o @ViewChild
é no processo de reset de formulários. Quando limpamos um formulário, ou seja, realizamos o "reset", é comum direcionar o foco para o primeiro elemento do formulário para facilitar a vida do usuário. Para isso, utilizo o @ViewChild
de maneira semelhante ao comando tradicional document.getElementById('id-do-input').focus()
. Veja o exemplo abaixo para entender melhor:
import {
Component,
ElementRef,
ViewChild
} from '@angular/core';
import {
FormControl,
FormGroup,
ReactiveFormsModule,
Validators
} from '@angular/forms';
@Component({
selector: 'app-exemplo3',
standalone: true,
imports: [ReactiveFormsModule],
template: `
<form [formGroup]="form" (ngSubmit)="salvar()">
<div>
<input
#nome
autofocus
formControlName="nome"
placeholder="nome..."
type="text"
/>
</div>
<div>
<input
formControlName="cargo"
placeholder="cargo..."
type="text"
/>
</div>
<div>
<input type="submit" value="Salvar" />
</div>
</form>
`
})
export class Exemplo3Component {
form = new FormGroup({
nome: new FormControl('', {
validators: [Validators.required]
}),
cargo: new FormControl('', {
validators: [Validators.required]
})
});
@ViewChild('nome') elNome!: ElementRef<HTMLInputElement>;
reset() {
this.form.reset();
this.elNome.nativeElement.focus();
}
salvar() {
if (this.form.invalid) {
return;
}
console.log('Valores do formulário', this.form.value);
this.reset();
}
}

Pegando a referência de um componente
Também é possível passar o nome da classe do componente que estamos pesquisando no template:
@ViewChild(NomeDoComponente) variavel: NomeDoComponente;
Essa abordagem é especialmente útil quando precisamos acessar recursos específicos do componente em si. No exemplo a seguir, o Exemplo4Component
utiliza o componente <app-ola>
em seu template. Utilizando o @ViewChild
podemos pegar a referência do componente e acessar os recursos do objeto, como por exemplo, chamar o método alterarTexto
da classe OlaComponent
(app-ola
):
import { Component } from '@angular/core';
@Component({
selector: 'app-ola',
standalone: true,
template: `<p>{{ texto }}</p>`
})
export class OlaComponent {
texto = 'olá!';
alterarTexto() {
this.texto = 'olá mundo!';
}
}
import { Component, ViewChild } from '@angular/core';
import { OlaComponent } from '../ola/ola.component';
@Component({
selector: 'app-exemplo4',
standalone: true,
imports: [OlaComponent],
template: `
<app-ola></app-ola>
<button (click)="testar()">testar</button>
`
})
export class Exemplo4Component {
@ViewChild(OlaComponent) olaComponent!: OlaComponent;
testar() {
// Acessando o método de um outro componente
this.olaComponent.alterarTexto();
}
}

Utilizando o novo viewChild
O lançamento da versão v17.2.0 marca outro passo significativo na jornada dos signals dentro do Angular com a introdução dos Queries Signals. Esta funcionalidade, ainda em developer preview, traz um conjunto de novas funções para realizar consultas de elementos: viewChild
, viewChildren
, contentChild
e contentChildren
.
A diferença é que, ao acessarmos um elemento filho, seu acesso é feito por meio de um Signal
, um tema previamente abordado aqui:

Veja no exemplo abaixo:
import {
Component,
ElementRef,
effect,
viewChild
} from '@angular/core';
import { OlaComponent } from '../ola/ola.component';
@Component({
selector: 'app-exemplo5',
standalone: true,
imports: [OlaComponent],
template: `
@if (mostrarDiv) {
<div #el>Olá sou o exemplo 5</div>
<app-ola></app-ola>
}
<button (click)="testar()">Testar</button>
<button (click)="mostrarDiv = !mostrarDiv">
Mostrar/Esconder Div
</button>
`
})
export class Exemplo5Component {
mostrarDiv = true;
divElement = viewChild<ElementRef<HTMLDivElement>>('el');
olaComponent = viewChild(OlaComponent);
constructor() {
// Como os elementos são acessados através do Signal,
// podemos por exemplo usar o effect.
// Caso tenha dúvidas sobre o effect ou Signal:
// https://consolelog.com.br/introducao-angular-signals
effect(() => {
console.log('div#el encontrado:', !!this.divElement());
console.log(
'olaComponent encontrado:',
!!this.olaComponent()
);
});
}
testar() {
console.log(`Div encontrado: ${!!this.divElement}`);
// Quando temos a certeza de que vamos encontrar o
// <app-ola>, podemos utilizar o required:
//
// olaComponent = viewChild.required(OlaComponent);
//
// Assim não precisamos do ?. (optional chaining operator)
this.olaComponent()?.alterarTexto();
}
}

Considerações
Além dos exemplos que citei neste texto, no passado já havia usado este recurso durante a implementação do Google ReCaptcha. Vou deixar o link abaixo:

Caso já tenha entendi bem o funcionamento do ViewChild, sugiro estudar ViewChildren, ContentChild e ContentChildren.
Abaixo há alguns links interessantes sobre o ViewChild:
- https://blog.angular.io/angular-v17-2-is-now-available-596cbe96242d
- https://angular.io/api/core/ViewChild#description
- https://www.digitalocean.com/community/tutorials/angular-viewchild-access-component-pt
Versões do Angular (fev/2024)
Version Status Released Active ends LTS ends
======= ====== ========== ========== ==========
^17.0.0 Active 2023-11-08 2024-05-08 2025-05-15
^16.0.0 LTS 2023-05-03 2023-11-08 2024-11-08
^15.0.0 LTS 2022-11-18 2023-05-03 2024-05-18
Fonte: https://angular.io/guide/releases#actively-supported-versions
ANGULAR NODEJS TYPESCRIPT RXJS
================== ================================== =============== ================
17.1.0 ^18.13.0 || ^20.9.0 >=5.2.0 <5.4.0 ^6.5.3 || ^7.4.0
17.0.x ^18.13.0 || ^20.9.0 >=5.2.0 <5.3.0 ^6.5.3 || ^7.4.0
16.1.x || 16.2.x ^16.14.0 || ^18.10.0 >=4.9.3 <5.2.0 ^6.5.3 || ^7.4.0
16.0.x ^16.14.0 || ^18.10.0 >=4.9.3 <5.1.0 ^6.5.3 || ^7.4.0
15.1.x || 15.2.x ^14.20.0 || ^16.13.0 || ^18.10.0 >=4.8.2 <5.0.0 ^6.5.3 || ^7.4.0
15.0.x ^14.20.0 || ^16.13.0 || ^18.10.0 ~4.8.2 ^6.5.3 || ^7.4.0
Fonte: https://angular.io/guide/versions#actively-supported-versions