基于blazor实现的一个简单的TODO List

最近看到一些大佬都开始关注blazor,我也想学习一下。做了一个小的demo,todolist,仅是一个小示例,参考此vue项目的实现http://www.jq22.com/code1339

先看实现的效果图

不BB,直接可以去看

源码与预览地址

源码介绍

我们这里删除了默认的一些源码。只保留最简单的结构,在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(部署)

在项目根目录执行如下命令

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 -t
nginx -s reload

打开网站看效果

http://baimocore.cn:8081

ASP.NET Core Blazor WebAssembly实现一个简单的TODO List的更多相关文章

  1. ASP.NET Core Blazor Webassembly 之 数据绑定

    上一次我们学习了Blazor组件相关的知识(Asp.net Core Blazor Webassembly - 组件).这次继续学习Blazor的数据绑定相关的知识.当代前端框架都离不开数据绑定技术. ...

  2. ASP.NET Core Blazor Webassembly 之 路由

    web最精妙的设计就是通过url把多个页面串联起来,并且可以互相跳转.我们开发系统的时候总是需要使用路由来实现页面间的跳转.传统的web开发主要是使用a标签或者是服务端redirect来跳转.那今天来 ...

  3. ASP.NET Core Blazor Webassembly 之 组件

    关于组件 现在前端几大轮子全面组件化.组件让我们可以对常用的功能进行封装,以便复用.组件这东西对于搞.NET的同学其实并不陌生,以前ASP.NET WebForm的用户控件其实也是一种组件.它封装ht ...

  4. [Asp.Net Core] Blazor WebAssembly - 工程向 - 如何在欢迎页面里, 预先加载wasm所需的文件

    前言, Blazor Assembly 需要最少 1.9M 的下载量.  ( Blazor WebAssembly 船新项目下载量测试 , 仅供参考. ) 随着程序越来越复杂, 引用的东西越来越多,  ...

  5. ASP.NET Core Blazor WebAssembly 之 .NET JavaScript互调

    Blazor WebAssembly可以在浏览器上跑C#代码,但是很多时候显然还是需要跟JavaScript打交道.比如操作dom,当然跟angular.vue一样不提倡直接操作dom:比如浏览器的后 ...

  6. ASP.NET Core Blazor Webassembly 之 渐进式应用(PWA)

    Blazor支持渐进式应用开发也就是PWA.使用PWA模式可以使得web应用有原生应用般的体验. 什么是PWA PWA应用是指那些使用指定技术和标准模式来开发的web应用,这将同时赋予它们web应用和 ...

  7. ASP.NET Core Blazor 初探之 Blazor WebAssembly

    最近Blazor热度很高,传说马上就要发布正式版了,做为微软脑残粉,赶紧也来凑个热闹,学习一下. Blazor Blazor是微软在ASP.NET Core框架下开发的一种全新的Web开发框架.Bla ...

  8. 学习ASP.NET Core Blazor编程系列二——第一个Blazor应用程序(上)

    学习ASP.NET Core Blazor编程系列一--综述 一.概述 Blazor 是一个生成交互式客户端 Web UI 的框架: 使用 C# 代替 JavaScript 来创建信息丰富的交互式 U ...

  9. 学习ASP.NET Core Blazor编程系列二——第一个Blazor应用程序(中)

    学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 四.创建一个Blazor应用程序 1. 第一种创 ...

随机推荐

  1. java 四舍五入 保留n为数

    double x1 = 0.026;String format = String.format("%.2f", x1);System.out.println(format); St ...

  2. 使用QQ同步助手备份同步手机数据

    QQ同步助手官网:https://pim.qq.com/ QQ同步助手,由腾讯精心打造的云端备份工具.能实现手机之间传输文件,并备份文件.照片.视频.联系人.短信.通讯记录.应用程序到云端的换手机必备 ...

  3. Vue路由的hash模式与history模式的区别?

    1.首先router有两种模式:hash模式(默认).history模式(需配置mode: 'history') hash和history的区别?   hash                    ...

  4. 数据结构----链表Link

    链表简介与数据结构 单向链表也叫单链表,是表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域.这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值. 单向链 ...

  5. WARN: Establishing SSL connection without server’s identity verification is not recommended

    问题 使用Spring JDBC 连接 MySQL时,出现如下警告: WARN: Establishing SSL connection without server's identity verif ...

  6. 【python爬虫】scrapy入门7:Scrapy中runspider和crawl的区别

    runspider:不依赖创建项目 命令:scrapy runspider myspider.py  等同于  pyhton myspider.py crawl:使用spider进行爬取,依赖项目创建 ...

  7. 【C#图解教程学习笔记】第13章 委托

    13.1 什么是委托 委托是持有一个或多个方法的对象,可将一个方法传递到另一个方法. 委托是用户自定义的引用类型. 13.2 委托概述 类表示的是数据和方法的集合,而委托持有一个或多个方法,以及一系列 ...

  8. 二、Spring装配Bean

    内容 声明bean 构造器注入和Setter方法注入 装配Bean 控制bean的创建和销毁 关键词 装配(wiring) 组件扫描(component scanning) 自动装配(AutoWiri ...

  9. spark学习笔记总结

    Spark简介 spark 可以很容易和yarn结合,直接调用HDFS.Hbase上面的数据,和hadoop结合.配置很容易. spark发展迅猛,框架比hadoop更加灵活实用.减少了延时处理,提高 ...

  10. python常见面试题讲解(八)提取不重复的整数

    题目描述 输入一个int型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数. 输入描述: 输入一个int型整数 输出描述: 按照从右向左的阅读顺序,返回一个不含重复数字的新的整数 示例1 ...