ASP.NET Core Blazor WebAssembly實現一個簡單的TODO List

基於blazor實現的一個簡單的TODO List

最近看到一些大佬都開始關注blazor,我也想學習一下。做了一個小的demo,todolist,僅是一個小示例,參考此vue項目的實現http://www.jq22.com/code1339

先看實現的效果圖

不BB,直接可以去看

源碼與預覽地址

  • 示例地址 http://baimocore.cn:8081/
  • 源碼地址 BlazorAppTodoList

源碼介紹

我們這裏刪除了默認的一些源碼。只保留最簡單的結構,在Pages/Index.razor中。

@code代碼結構中寫如下內容

  1. 創建一個類,裡面包含 id,label,isdone三個屬性值。
public class TodoItem
{
    public TodoItem () { }
    public TodoItem (int id, string label, bool isDone)
    {
        Id = id;
        Label = label;
        IsDone = isDone;
    }
    public int Id { get; set; }
    public string Label { get; set; }
    public bool IsDone { get; set; }
}
  1. 我們可以通過override重寫初始化,並給Todos設置一些數據。
private IList<TodoItem> Todos;
private int id = 0;
protected override void OnInitialized ()
{
    Todos = new List<TodoItem> ()
    {
        new TodoItem (++id, "Learn Blazor", false),
        new TodoItem (++id, "Code a todo list", false),
        new TodoItem (++id, "Learn something else", false)
    };
}

展示還有多少未完成的任務

<h1>
        Todo List(@Todos.Count(todo => !todo.IsDone))
        <span>Get things done, one item at a time.</span>
</h1>

當任務沒有時,我們展示默認效果,提示用戶無任務

<p class="emptylist" style="display: @(Todos.Count()>0?"none":"");">Your todo list is empty.</p>

新增一個任務

<form name="newform">
    <label for="newitem">Add to the todo list</label>
    <input type="text" name="newitem" id="newitem" @bind-value="Label">
    <button type="button" @onclick="AddItem">Add item</button>
</form>

這裏我們用了一個Label變量,一個onclick事件。

private string Label;

private void AddItem()
{
    if (!string.IsNullOrWhiteSpace(Label))
    {
        Todos.Add (new TodoItem { Id = ++id, Label = Label });
        Label = string.Empty;
    }
    this.SortByStatus();
}

this.SortByStatus
因為我們這裏還實現一個功能,就是當勾選(當任務完成時,我們將他移到最下面)

<div class="togglebutton-wrapper@(IsActive==true?" togglebutton-checked":"")">
    <label for="todosort">
        <span class="togglebutton-Label">Move done items at the end?</span>
        <span class="tooglebutton-box"></span>
    </label>
    <input type="checkbox" name="todosort" id="todosort" value="@IsActive" @onchange="ActiveChanged">
</div>

一個IsActive的變量,用於指示當前checkbox的樣式,是否開啟已完成的任務移動到最下面。當勾選時,改變IsActive的值。並調用排序的功能。

private bool IsActive = false;
private void ActiveChanged()
{
    this.IsActive = !this.IsActive;
    this.SortByStatus();
}
private void SortByStatus()
{
    if (this.IsActive)
    {
        Todos = Todos.OrderBy(r => r.IsDone).ThenByDescending(r => r.Id).ToList();
    }
    else
    {
        Todos = Todos.OrderByDescending(r => r.Id).ToList();
    }
}

對於列表的展示我們使用如下ul li @for實現

<ul>
    @foreach (var item in Todos)
    {
        <li stagger="5000" class="@(item.IsDone?"done":"")">
            <span class="label">@item.Label</span>
            <div class="actions">
                <button class="btn-picto" type="button"
                        @onclick="@((e)=> {MarkAsDoneOrUndone(item);})"
                        title="@(item.IsDone ? "Undone" :"Done")"
                        aria-label="@(item.IsDone ? "Undone" :"Done")">
                    <i aria-hidden="true" class="material-icons">@(item.IsDone ? "check_box" : "check_box_outline_blank")</i>
                </button>
                <button class="btn-picto" type="button"
                        @onclick="@((e)=> { DeleteItemFromList(item); })"
                        aria-Label="Delete" title="Delete">
                    <i aria-hidden="true" class="material-icons">delete</i>
                </button>
            </div>
        </li>
    }
</ul>

循環Todos,然後,根據item.IsDone,改變li的樣式,從而實現一个中劃線的功能,二個按鈕的功能,一個是勾選任務表示此任務已完成,另一個是刪除此任務。同理,我們仍然通過IsDone來標識完成任務的圖標,標題等。

  • 任務設置已完成/設置為未完成: @onclick調用方法MarkAsDoneOrUndone,並將當前的一行記錄item傳給方法,需要使用一個匿名函數調用@code中的方法,將isDone取相反的值,並重新排序。
private void MarkAsDoneOrUndone(TodoItem item)
{
    item.IsDone = !item.IsDone;
    this.SortByStatus();
}
  • 刪除一個任務,同理,使用匿名函數,DeleteItemFromList直接通過IList的方法Remove刪除一個對象,並排序。
private void DeleteItemFromList(TodoItem item)
{
    Todos.Remove(item);
    this.SortByStatus();
}

當然,我們可以 在ul,外包裹一層,根據Count判斷有沒有任務,從而显示這個列表。

<div style="display: @(Todos.Count()>0?"":"none");"><ul>xxx</ul></div>

其他的樣式與圖標,請看最上面的源碼wwwroot/css目錄獲取。

deploy(部署)

  • 有興趣的可以看官網 https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/blazor/?view=aspnetcore-3.1&tabs=visual-studio

在項目根目錄執行如下命令

dotnet publish -c Release

我們就能得到一個發布包,他的位置在 (BlazorAppTodoList\bin\Release\netstandard2.1\publish) ,我們把他複製到服務器上,這裏我放到/var/www/todolilst目錄中。

它相當於一個靜態文件,你可以將他部署到任何一個web服務器上。

這裏我們把他放到nginx中,並在目錄/etc/nginx/conf.d/ 新建一個文件 todolist.conf,然後放入如下內容。

 server {
        listen 8081;

        location / {
            root /var/www/todolist/wwwroot;
            try_files $uri $uri/ /index.html =404;
        }
}

記得在etc/nginx/nginx.conf中配置gzip壓縮。

gzip  on;
gzip_min_length 5k; #gzip壓縮最小文件大小,超出進行壓縮(自行調節)
gzip_buffers 4 16k; #buffer 不用修改
gzip_comp_level 8; #壓縮級別:1-10,数字越大壓縮的越好,時間也越長
gzip_types text/plain application/x-javascript application/javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/octet-stream; #  壓縮文件類型 
gzip_vary on; # 和http頭有關係,加個vary頭,給代理服務器用的,有的瀏覽器支持壓縮,有的不支持,所以避免浪費不支持的也壓縮,所以根據客戶端的HTTP頭來判斷,是否需要壓縮

我遇到dll,wasm,後綴的文件壓縮無效。因為gzip_types ,沒有配置他們的Content-Type。我們在瀏覽器中找到響應頭Content-Type: application/octet-stream,然後在上文中的nginx配置文件中,gzip_types加上application/octet-stream,

最後執行

nginx -t
nginx -s reload

打開網站看效果

http://baimocore.cn:8081

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

※教你寫出一流的銷售文案?

※回頭車貨運收費標準

※別再煩惱如何寫文案,掌握八大原則!