Criar um aplicativo de lista de tarefas pendentesBlazor

Observação

Esta não é a versão mais recente deste artigo. Para informações sobre a versão vigente, confira a Versão do .NET 8 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 informações sobre a versão vigente, confira a Versão do .NET 8 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 aplicativo Web Blazor nomeado 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 TodoRazor 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 @pageRazor 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 @pageRazor 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 @pageRazor com uma URL relativa de /todo.

Todo.razor:

@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:

namespace BlazorSample;

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 componente Todo 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();
}

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"

<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 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"

<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"

<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: