Criar um aplicativo de lista de tarefas pendentesBlazor
Observação
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 9 deste artigo.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, consulte a Política de Suporte do .NET e do .NET Core. Para a versão atual, consulte a versão .NET 9 deste artigo.
Importante
Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.
Para a versão atual, consulte a versão .NET 9 deste artigo.
Este tutorial fornece uma experiência de trabalho básica para criar e modificar um aplicativo Blazor. Para obter diretrizes do Blazor mais detalhadas, confira a documentação de referência do Blazor.
Saiba como:
- Criar um projeto de aplicativo Blazor de lista de tarefas pendentes
- Modificar componentes Razor
- Usar a manipulação de eventos e a associação de dados em componentes
- Usar o roteamento em um aplicativo Blazor
Ao final deste tutorial, você terá um aplicativo de lista de tarefas pendentes.
Pré-requisitos
Baixe e instale o .NET se ele ainda não estiver instalado no sistema ou se o sistema não tiver a versão mais recente instalada.
Criar um aplicativo Blazor
Crie um novo Blazor Web App chamado TodoList
em um shell de comando:
dotnet new blazor -o TodoList
A opção -o|--output
cria uma pasta para o projeto. Se você criou uma pasta para o projeto e o shell de comando está aberto nessa pasta, omita a opção -o|--output
e o valor para criar o projeto.
Use qualquer um dos seguintes modelos de hospedagem para criar um novo aplicativo Blazor chamado TodoList
em um shell de comando:
Para obter uma experiência com Blazor Server, crie o aplicativo com o seguinte comando:
dotnet new blazorserver -o TodoList
Para obter uma experiência com Blazor WebAssembly, crie o aplicativo com o seguinte comando:
dotnet new blazorwasm -o TodoList
O comando anterior cria uma pasta chamada TodoList
com a opção -o|--output
para manter o aplicativo. A pasta TodoList
é a pasta raiz do projeto. Altere os diretórios para a pasta TodoList
com o seguinte comando:
cd TodoList
Criar um aplicativo de lista de tarefas pendentesBlazor
Adicione um novo componente Todo
Razor ao aplicativo usando o seguinte comando:
dotnet new razorcomponent -n Todo -o Components/Pages
A opção -n|--name
no comando anterior especifica o nome do novo componente Razor. O componente é criado na pasta Components/Pages
do projeto com a opção -o|--output
.
dotnet new razorcomponent -n Todo -o Pages
A opção -n|--name
no comando anterior especifica o nome do novo componente Razor. O componente é criado na pasta Pages
do projeto com a opção -o|--output
.
Importante
Os nomes de arquivo do componente Razor exigem a primeira letra em maiúscula. Abra a pasta Pages
e confirme se o nome de arquivo do componente Todo
começa com uma letra maiúscula T
. O nome de arquivo será Todo.razor
.
Abra o componente Todo
em qualquer editor de arquivos e faça as seguintes alterações na parte superior do arquivo:
- Adicione uma diretiva
@page
Razor com uma URL relativa de/todo
. - Habilite a interatividade na página para que ela não seja apenas renderizada estaticamente. O modo de renderização do Servidor Interativo permite que o componente manipule eventos de interface do usuário do servidor.
- Adicione um título de página com o componente
PageTitle
, que permite adicionar um elemento HTML<title>
à página.
Abra o componente Todo
em qualquer editor de arquivos e faça as seguintes alterações na parte superior do arquivo:
- Adicione uma diretiva
@page
Razor com uma URL relativa de/todo
. - Adicione um título de página com o componente
PageTitle
, que permite adicionar um elemento HTML<title>
à página.
Abra o componente Todo
em qualquer editor de arquivo e adicione uma diretiva @page
Razor com uma URL relativa de /todo
.
Todo.razor
:
@page "/todo"
@rendermode InteractiveServer
<PageTitle>Todo</PageTitle>
<h3>Todo</h3>
@code {
}
@page "/todo"
@rendermode InteractiveServer
<PageTitle>Todo</PageTitle>
<h3>Todo</h3>
@code {
}
@page "/todo"
<PageTitle>Todo</PageTitle>
<h3>Todo</h3>
@code {
}
@page "/todo"
<PageTitle>Todo</PageTitle>
<h3>Todo</h3>
@code {
}
@page "/todo"
<h3>Todo</h3>
@code {
}
@page "/todo"
<h3>Todo</h3>
@code {
}
Salve o arquivo Todo.razor
.
Adicione o componente Todo
à barra de navegação.
O componente NavMenu
é usado no layout do aplicativo. Layouts são componentes que permitem evitar a duplicação de conteúdo em um aplicativo. O componente NavLink
fornece uma indicação na interface do usuário do aplicativo quando a URL do componente é carregada pelo aplicativo.
No conteúdo do elemento de navegação (<nav>
) do componente NavMenu
, adicione o seguinte elemento <div>
para o componente Todo
.
Em Components/Layout/NavMenu.razor
:
Em Shared/NavMenu.razor
:
<div class="nav-item px-3">
<NavLink class="nav-link" href="todo">
<span class="oi oi-list-rich" aria-hidden="true"></span> Todo
</NavLink>
</div>
Salve o arquivo NavMenu.razor
.
Compile e execute o aplicativo executando o comando dotnet watch run
no shell de comando da pasta TodoList
. Depois que o aplicativo estiver em execução, visite a nova página de tarefa pendente selecionando o link Todo
na barra de navegação do aplicativo, que carrega a página em /todo
.
Deixe o aplicativo executando o shell de comando. Sempre que um arquivo é salvo, o aplicativo é recriado automaticamente e a página no navegador é recarregada automaticamente.
Adicione um arquivo TodoItem.cs
à raiz do projeto (a pasta TodoList
) para manter uma classe que representará um item de tarefa pendente. Use o seguinte código de C# para a classe TodoItem
.
TodoItem.cs
:
public class TodoItem
{
public string? Title { get; set; }
public bool IsDone { get; set; }
}
public class TodoItem
{
public string? Title { get; set; }
public bool IsDone { get; set; }
}
public class TodoItem
{
public string? Title { get; set; }
public bool IsDone { get; set; }
}
public class TodoItem
{
public string? Title { get; set; }
public bool IsDone { get; set; }
}
public class TodoItem
{
public string Title { get; set; }
public bool IsDone { get; set; }
}
public class TodoItem
{
public string Title { get; set; }
public bool IsDone { get; set; }
}
Observação
Se estiver usando o Visual Studio para criar o arquivo TodoItem.cs
e a classe TodoItem
, use uma das seguintes abordagens:
- Remova o namespace gerado pelo Visual Studio para a classe.
- Use o botão Copiar no bloco de código anterior e substitua todo o conteúdo do arquivo gerado pelo Visual Studio.
Retorne ao componente Todo
e execute as seguintes tarefas:
- Adicione um campo para os itens de tarefas pendentes ao bloco
@code
. O componenteTodo
usa esse campo para manter o estado da lista de tarefas pendentes. - Adicione marcação da lista não ordenada e um loop
foreach
para renderizar cada item de tarefa pendente como um item de lista (<li>
).
Components/Pages/Todo.razor
:
@page "/todo"
@rendermode InteractiveServer
<PageTitle>Todo</PageTitle>
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
@code {
private List<TodoItem> todos = new();
}
Components/Pages/Todo.razor
:
@page "/todo"
@rendermode InteractiveServer
<PageTitle>Todo</PageTitle>
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
@code {
private List<TodoItem> todos = new();
}
Pages/Todo.razor
:
@page "/todo"
<PageTitle>Todo</PageTitle>
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
@code {
private List<TodoItem> todos = new();
}
Pages/Todo.razor
:
@page "/todo"
<PageTitle>Todo</PageTitle>
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
@code {
private List<TodoItem> todos = new();
}
Pages/Todo.razor
:
@page "/todo"
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
@code {
private List<TodoItem> todos = new();
}
Pages/Todo.razor
:
@page "/todo"
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
@code {
private IList<TodoItem> todos = new List<TodoItem>();
}
O aplicativo requer elementos de interface do usuário para adicionar itens de tarefas à lista. Adicione uma entrada de texto (<input>
) e um botão (<button>
) abaixo da lista não ordenada (<ul>...</ul>
):
@page "/todo"
@rendermode InteractiveServer
<PageTitle>Todo</PageTitle>
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" />
<button>Add todo</button>
@code {
private List<TodoItem> todos = new();
}
@page "/todo"
@rendermode InteractiveServer
<PageTitle>Todo</PageTitle>
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" />
<button>Add todo</button>
@code {
private List<TodoItem> todos = new();
}
@page "/todo"
<PageTitle>Todo</PageTitle>
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" />
<button>Add todo</button>
@code {
private List<TodoItem> todos = new();
}
@page "/todo"
<PageTitle>Todo</PageTitle>
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" />
<button>Add todo</button>
@code {
private List<TodoItem> todos = new();
}
@page "/todo"
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" />
<button>Add todo</button>
@code {
private List<TodoItem> todos = new();
}
@page "/todo"
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" />
<button>Add todo</button>
@code {
private IList<TodoItem> todos = new List<TodoItem>();
}
Salve o arquivo TodoItem.cs
e o arquivo Todo.razor
atualizado. No shell de comando, o aplicativo é recriado automaticamente quando os arquivos são salvos. O navegador recarrega a página.
Nada acontece quando o botão Add todo
é selecionado, porque nenhum manipulador de eventos está anexado ao botão.
Adicione um método AddTodo
ao componente Todo
e registre o método para o botão usando o atributo @onclick
. O método C# AddTodo
é chamado quando o botão é selecionado:
<input placeholder="Something todo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private void AddTodo()
{
// Todo: Add the todo
}
}
<input placeholder="Something todo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private void AddTodo()
{
// Todo: Add the todo
}
}
<input placeholder="Something todo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private void AddTodo()
{
// Todo: Add the todo
}
}
<input placeholder="Something todo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private void AddTodo()
{
// Todo: Add the todo
}
}
<input placeholder="Something todo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private void AddTodo()
{
// Todo: Add the todo
}
}
<input placeholder="Something todo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private IList<TodoItem> todos = new List<TodoItem>();
private void AddTodo()
{
// Todo: Add the todo
}
}
Para obter o título do novo item de tarefa pendente, adicione um campo de cadeia de caracteres newTodo
no início do bloco @code
:
private string? newTodo;
private string newTodo;
Modifique o elemento <input>
do texto para associar newTodo
ao atributo @bind
:
<input placeholder="Something todo" @bind="newTodo" />
Atualize o método AddTodo
para adicionar o TodoItem
com o título especificado à lista. Limpe o valor da entrada de texto configurando newTodo
para uma cadeia de caracteres vazia:
@page "/todo"
@rendermode InteractiveServer
<PageTitle>Todo</PageTitle>
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private string? newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
@page "/todo"
@rendermode InteractiveServer
<PageTitle>Todo</PageTitle>
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private string? newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
@page "/todo"
<PageTitle>Todo</PageTitle>
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private string? newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
@page "/todo"
<PageTitle>Todo</PageTitle>
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private string? newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
@page "/todo"
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private string newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
@page "/todo"
<h3>Todo</h3>
<ul>
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private IList<TodoItem> todos = new List<TodoItem>();
private string newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
Salve o arquivo Todo.razor
. O aplicativo é recriado automaticamente no shell de comando e a página é recarregada no navegador.
O texto do título de cada item de tarefa pode se tornar editável, e uma caixa de seleção pode ajudar o usuário a acompanhar os itens concluídos. Adicione uma entrada de caixa de seleção para cada item de tarefa pendente e associe o valor dele à propriedade IsDone
. Altere @todo.Title
para um elemento <input>
associado a todo.Title
com @bind
:
<ul>
@foreach (var todo in todos)
{
<li>
<input type="checkbox" @bind="todo.IsDone" />
<input @bind="todo.Title" />
</li>
}
</ul>
Atualize o cabeçalho <h3>
para mostrar uma contagem do número de itens de tarefas pendentes que não foram concluídos (IsDone
é false
). A expressão Razor no cabeçalho a seguir é avaliada sempre que Blazor remete o componente novamente.
<h3>Todo (@todos.Count(todo => !todo.IsDone))</h3>
O componente concluído Todo
:
@page "/todo"
@rendermode InteractiveServer
<PageTitle>Todo</PageTitle>
<h1>Todo (@todos.Count(todo => !todo.IsDone))</h1>
<ul>
@foreach (var todo in todos)
{
<li>
<input type="checkbox" @bind="todo.IsDone" />
<input @bind="todo.Title" />
</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private string? newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
@page "/todo"
@rendermode InteractiveServer
<PageTitle>Todo</PageTitle>
<h1>Todo (@todos.Count(todo => !todo.IsDone))</h1>
<ul>
@foreach (var todo in todos)
{
<li>
<input type="checkbox" @bind="todo.IsDone" />
<input @bind="todo.Title" />
</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private string? newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
@page "/todo"
<PageTitle>Todo</PageTitle>
<h1>Todo (@todos.Count(todo => !todo.IsDone))</h1>
<ul>
@foreach (var todo in todos)
{
<li>
<input type="checkbox" @bind="todo.IsDone" />
<input @bind="todo.Title" />
</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private string? newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
@page "/todo"
<PageTitle>Todo</PageTitle>
<h1>Todo (@todos.Count(todo => !todo.IsDone))</h1>
<ul>
@foreach (var todo in todos)
{
<li>
<input type="checkbox" @bind="todo.IsDone" />
<input @bind="todo.Title" />
</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private string? newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
@page "/todo"
<h1>Todo (@todos.Count(todo => !todo.IsDone))</h1>
<ul>
@foreach (var todo in todos)
{
<li>
<input type="checkbox" @bind="todo.IsDone" />
<input @bind="todo.Title" />
</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private string? newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
@page "/todo"
<h1>Todo (@todos.Count(todo => !todo.IsDone))</h1>
<ul>
@foreach (var todo in todos)
{
<li>
<input type="checkbox" @bind="todo.IsDone" />
<input @bind="todo.Title" />
</li>
}
</ul>
<input placeholder="Something todo" @bind="newTodo" />
<button @onclick="AddTodo">Add todo</button>
@code {
private List<TodoItem> todos = new();
private string? newTodo;
private void AddTodo()
{
if (!string.IsNullOrWhiteSpace(newTodo))
{
todos.Add(new TodoItem { Title = newTodo });
newTodo = string.Empty;
}
}
}
Salve o arquivo Todo.razor
. O aplicativo é recriado automaticamente no shell de comando e a página é recarregada no navegador.
Adicione, edite e marque itens de tarefas pendentes como concluídos para testar o componente.
Quando terminar, desligue o aplicativo no shell de comando. Muitos shells de comando aceitam o comando de teclado Ctrl+C (Windows) ou ⌘+C (macOS) para interromper um aplicativo.
Publicar no Azure
Para obter informações sobre como implantar no Azure, consulte Início Rápido: Implantar um aplicativo Web ASP.NET.
Próximas etapas
Neste tutorial, você aprendeu a:
- Criar um projeto de aplicativo Blazor de lista de tarefas pendentes
- Modificar componentes Razor
- Usar a manipulação de eventos e a associação de dados em componentes
- Usar o roteamento em um aplicativo Blazor
Saiba mais sobre ferramentas para ASP.NET Core Blazor: