建置 Blazor 待辦事項清單應用程式
注意
這不是這篇文章的最新版本。 如需目前的版本,請參閱 本文的 .NET 9 版本。
警告
不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支持原則。 如需目前的版本,請參閱 本文的 .NET 9 版本。
本教學課程提供建置和修改 Blazor 應用程式的基本工作體驗。 如需詳細 Blazor 指引,請參閱Blazor參考文件。
了解如何:
- 建立待辦事項清單 Blazor 應用程式專案
- 修改 Razor 元件
- 在元件中使用事件處理和資料繫結
- 在 Blazor 應用程式中使用路由
在本教學課程結束時,您將有一個可運作的待辦事項清單應用程式。
必要條件
如果尚未安裝在系統上,或系統尚未安裝最新版本,請下載並安裝 .NET。
建立 Blazor 應用程式
在命令殼層中建立名為 TodoList
的新 Blazor Web App:
dotnet new blazor -o TodoList
-o|--output
選項會為專案建立資料夾。 如果您已為專案建立資料夾,且命令殼層在該資料夾中開啟,請省略 -o|--output
選項和值以建立專案。
使用下列任一裝載模型,在命令殼層中建立名為 TodoList
的新 Blazor 應用程式:
如需 Blazor Server 的體驗,請使用下列命令建立應用程式:
dotnet new blazorserver -o TodoList
如需 Blazor WebAssembly 的體驗,請使用下列命令建立應用程式:
dotnet new blazorwasm -o TodoList
上述命令會使用 -o|--output
選項來建立名為 TodoList
的資料夾,以保存應用程式。 TodoList
資料夾是專案的根資料夾。 使用下列命令將目錄變更為 TodoList
資料夾:
cd TodoList
建置待辦事項清單 Blazor 應用程式
使用下列命令將新的 Todo
Razor 元件新增至應用程式:
dotnet new razorcomponent -n Todo -o Components/Pages
上述命令中的 -n|--name
選項會指定新 Razor 元件的名稱。 您可以使用 -o|--output
選項,在專案的 Components/Pages
資料夾中建立新的元件。
dotnet new razorcomponent -n Todo -o Pages
上述命令中的 -n|--name
選項會指定新 Razor 元件的名稱。 您可以使用 -o|--output
選項,在專案的 Pages
資料夾中建立新的元件。
重要
Razor 元件檔案名的第一個字母需為大寫。 開啟 Pages
資料夾,並確認 Todo
元件檔案名稱以大寫字母 T
開頭。 檔案名稱應該是 Todo.razor
。
在任何檔案編輯器中開啟 Todo
元件,並在檔案頂端進行下列變更:
- 新增具有相對 URL
/todo
的@page
Razor 指示詞。 - 啟用頁面上的互動功能,使其不只是以靜態方式轉譯。 互動式伺服器轉譯模式可讓元件處理來自伺服器的 UI 事件。
- 使用
PageTitle
元件新增頁面標題,以將 HTML<title>
元素新增至頁面。
在任何檔案編輯器中開啟 Todo
元件,並在檔案頂端進行下列變更:
- 新增具有相對 URL
/todo
的@page
Razor 指示詞。 - 使用
PageTitle
元件新增頁面標題,以將 HTML<title>
元素新增至頁面。
在任何檔案編輯器中開啟 Todo
元件,並使用相對 URL /todo
新增 @page
Razor 指示詞。
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 {
}
儲存Todo.razor
檔案。
將 Todo
元件新增至導覽列。
NavMenu
元件會用於應用程式版面配置。 版面配置是可讓您避免應用程式中內容重複的元件。 當應用程式載入元件 URL 時,NavLink
元件會在應用程式的 UI 中提供提示。
在 NavMenu
元件的導覽元素 (<nav>
) 內容中,為 Todo
元件新增下列 <div>
元素。
在 Components/Layout/NavMenu.razor
中:
在 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>
儲存NavMenu.razor
檔案。
從 TodoList
資料夾在命令殼層中執行 dotnet watch run
命令,以建置並執行應用程式。 執行應用程式之後,請選取應用程式導覽列中的 Todo
連結,在 /todo
載入頁面,以瀏覽新的待辦事項頁面。
讓應用程式保持執行命令殼層。 每次儲存檔案時,系統都會自動重建應用程式,且瀏覽器中的頁面會自動重新載入。
將 TodoItem.cs
檔案新增至專案的根目錄 (TodoList
資料夾),以保存代表待辦事項項目的類別。 對於 TodoItem
類別,使用下列 C# 程式碼。
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; }
}
注意
如果使用 Visual Studio 建立 TodoItem.cs
檔案和 TodoItem
類別,請使用下列其中一種方法:
- 移除 Visual Studio 為類別產生的命名空間。
- 使用上述程式碼區塊中的 [複製] 按鈕,並取代 Visual Studio 產生的整個檔案內容。
返回 Todo
元件並執行下列工作:
- 在
@code
區塊中新增待辦項目的欄位。Todo
元件會使用此欄位來維持待辦清單的狀態。 - 新增未排列的清單標記和
foreach
迴圈,將每個待辦項目轉譯為清單項目 (<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>();
}
應用程式需要 UI 元素,才能將待辦項目新增至清單中。 新增文字輸入 (<input>
),並將按鈕 (<button>
) 新增至未排序清單 (<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>();
}
儲存 TodoItem.cs
檔案和 Todo.razor
的更新檔案。 在命令殼層中,儲存檔案時會自動重建應用程式。 瀏覽器會重新載入頁面。
選取 Add todo
按鈕時,不會發生任何情況,因為事件處理常式並未連接至這個按鈕。
將 AddTodo
方法新增至 Todo
元件,並且使用 @onclick
屬性來註冊按鈕的方法。 選取按鈕時,會呼叫 AddTodo
C# 方法:
<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
}
}
若要取得新待辦事項項目的標題,在 @code
區塊的頂端新增 newTodo
字串欄位:
private string? newTodo;
private string newTodo;
修改文字 <input>
元素,以繫結 newTodo
與 @bind
屬性:
<input placeholder="Something todo" @bind="newTodo" />
更新 AddTodo
方法,將具有指定標題的 TodoItem
新增至清單中。 將 newTodo
設定為空白字串以清除文字輸入的值:
@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;
}
}
}
儲存Todo.razor
檔案。 應用程式會自動在命令殼層中重建,而頁面會在瀏覽器中重載。
每個待辦事項的標題文字都可設定為可編輯,而核取方塊則可協助使用者追蹤已完成的項目。 請為每個待辦事項新增核取方塊輸入,然後將其值繫結至 IsDone
屬性。 將 @todo.Title
變更為 <input>
元素,使用 @bind
繫結至 todo.Title
:
<ul>
@foreach (var todo in todos)
{
<li>
<input type="checkbox" @bind="todo.IsDone" />
<input @bind="todo.Title" />
</li>
}
</ul>
更新 <h3>
標頭,以顯示未完成待辦事項 (IsDone
為 false
) 的數目計數。 下列標頭中的 Razor 運算式會在每次 Blazor 重新調整元件時進行評估。
<h3>Todo (@todos.Count(todo => !todo.IsDone))</h3>
已完成的 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;
}
}
}
儲存Todo.razor
檔案。 應用程式會自動在命令殼層中重建,而頁面會在瀏覽器中重載。
新增項目、編輯項目,以及標記完成的待辦事項以測試元件。
完成後,關閉命令殼層中的應用程式。 許多命令殼層接受鍵盤命令 Ctrl+C (Windows) 或 ⌘+C (macOS) 停止應用程式。
發佈至 Azure
如需部署至 Azure 的資訊,請參閱 快速入門:部署 ASP.NET Web 應用程式。
下一步
在本教學課程中,您已了解如何:
- 建立待辦事項清單 Blazor 應用程式專案
- 修改 Razor 元件
- 在元件中使用事件處理和資料繫結
- 在 Blazor 應用程式中使用路由
了解 ASP.NET Core Blazor的工具: