石头 ✊ 纸 ✋ 剪刀 ✌️
Source: Dev.to
请提供您希望翻译的正文内容,我将把它译成简体中文并保持原有的格式、Markdown 语法以及技术术语不变。谢谢!
Source: https://github.com/webforms-core
什么是 WebForms Core?
WebForms Core 是来自 Elanat 的一种新多平台技术,旨在与现代前端框架竞争——它 不是 在 .NET Core 上的旧移植版本。
示例:石头 剪刀 布
此示例是使用 WebForms Core 完全离线实现的。命令在服务器上编写,并向客户端声明行为。
注意: 示例的 HTML 输出可以复制并离线使用,无需服务器。
与其他服务器驱动的 UI 系统不同,WebForms Core 的服务器与 HTML 没有直接关联;它是无状态且完全盲目的。这种“服务器盲目性”带来了若干好处:
- 灵活性 – 服务器可以为不同的客户端(网页、移动端、桌面端)提供不同的视图。
- 可扩展性 – 不同团队可以并行工作于服务器端和客户端。
- 更易维护 – 更改站点外观不需要修改服务器逻辑。
- 安全性 – 数据以原始形式传输,客户端仅显示所需内容。
- 可复用性 – 内置 API 可在多个项目中使用。
金句
服务器不是因为不理解而盲目;
而是因为它不需要看到。
HTML
@page
@controller RockPaperScissorsController
WebForms Core Technology
石头 ✊ 纸张 ✋ 剪刀 ✌️
石头 ✊
纸张 ✋
剪刀 ✌️
计算机选择:
游戏局数: 0
游戏胜利: 0
## 服务器代码
```csharp
using CodeBehind;
public partial class RockPaperScissorsController : CodeBehindController
{
public void PageLoad(HttpContext context)
{
WebForms form = new WebForms();
form.SetCommentEvent("*", HtmlEvent.OnClick, "play");
form.StartIndex("play");
form.Increase("counter|", 1);
form.AddSessionCacheValue("random", Fetch.Random(0, 3));
form.SetText("result", "😢 You lose!");
form.IsEqualTo(Fetch.GetAttribute("$", "win-with"), Fetch.Saved("random"));
form.StartBracket();
form.SetText("result", "😀 You win!");
form.Increase("win-counter|", 1);
form.EndBracket();
form.IsEqualTo(Fetch.GetAttribute("$", "value"), Fetch.Saved("random"));
form.SetText("result", "😐 Equal!");
form.IsEqualTo("0", Fetch.Saved("random"));
form.SetText("computer|", "Rock ✊");
form.IsEqualTo("1", Fetch.Saved("random"));
form.SetText("computer|", "Paper ✋");
form.IsEqualTo("2", Fetch.Saved("random"));
form.SetText("computer|", "Scissors ✌️");
Write(form.ExportToHtmlComment());
}
}
结果(HTML 嵌入 WebForms 注释)
*=onclick|play|
#=play
gtcounter|=i|1
SA=random|@mr3,0
stresult=😢 You lose!
{et=@$a$,win-with|@csrandom
{
stresult=😀 You win!
gtwin-counter|=i|1
}
{et=@$a$,value|@csrandom
stresult=😐 Equal!
{et=0|@csrandom
stcomputer|=Rock ✊
{et=1|@csrandom
stcomputer|=Paper ✋
{et=2|@csrandom
stcomputer|=Scissors ✌️-->
WebForms Core Technology
## Rock ✊ Paper ✋ Scissors ✌️
Rock ✊
Paper ✋
Scissors ✌️
Computer choice:
Game match: 0
Game win: 0
示例概览
本示例演示了一个完全交互式的石头‑剪刀‑布游戏,无需编写任何 JavaScript 业务逻辑。
- 所有游戏逻辑在服务器端运行。
- 浏览器接收干净、标准的 HTML。
- 轻量级客户端引擎执行声明式指令。
- 交互过程中不会发生页面重新加载。
HTML 部分:仅结构,无逻辑
HTML 仅定义用户界面:
Rock ✊
Paper ✋
Scissors ✌️
关键点
value表示用户的选择。win-with定义哪种选项能够击败当前选择。
服务器端声明式行为定义
在服务器上创建了一个 WebForms 对象,并以声明方式定义整个页面的行为。
事件绑定
form.SetCommentEvent("*", HtmlEvent.OnClick, "play");
当任意元素被点击时,触发名为 play 的事件。
逻辑入口
form.StartIndex("play");
随后所有逻辑仅在 play 事件被触发时运行。
游戏逻辑 – 步骤详解
1. 增加匹配计数器
form.Increase("counter|", 1);
每次点击都会增加总匹配次数。
2. 生成电脑的选择
form.AddSessionCacheValue("random", Fetch.Random(0, 3));
生成一个随机值(0‑2),并将其存入会话。
3. 默认结果 – 失败
form.SetText("result", "😢 You lose!");
游戏默认认为玩家失败;后续条件可能会覆盖此结果。
4. 检查用户胜利
如果点击的按钮的 win-with 属性与电脑的选择相匹配:
form.SetText("result", "😀 You win!");
form.Increase("win-counter|", 1);
更新结果并增加胜利计数器。
5. 检查平局
如果按钮的 value 与电脑的选择相匹配:
form.SetText("result", "😐 Equal!");
游戏以平局结束。
6. 显示电脑的选择
| 随机值 | 显示文本 |
|---|---|
0 | 石头 ✊ |
1 | 布 ✋ |
2 | 剪刀 ✌️ |
最终输出 – HTML 注释中的 DSL
All server‑defined behavior is exported as a compact DSL and embedded into the HTML as a comment:
*=onclick|play|
#=play
gtcounter|=i|1
...
-->
- 该注释会被浏览器的渲染引擎忽略。
- 它会被 WebForms Core 客户端引擎解析。
- 支持局部 DOM 更新,避免整页重新加载。
- 保持 HTML 干净且不受影响。
最终结果
该示例演示了使用 WebForms Core 时:
- HTML 仍然仅用于结构——没有 JavaScript、条件或事件处理程序。
- 所有业务逻辑都在服务器端处理。
- JavaScript 仅充当轻量级执行引擎。
- UI 更新是响应式的,无需使用 SPA 框架。
石头‑剪刀‑布演示展示了 WebForms Core 如何在保持传统 HTML 的简洁和清晰的同时,实现 现代、状态化、交互式的 Web 应用程序。
这个例子证明了什么?
1. WebForms Core 是真正的服务器驱动 UI
- 没有 PostBack,没有 ViewState。
- 事件类似声明式。
- 状态在服务器上确定并发送到客户端。
- 只将逻辑差异传输到客户端。
这与现代 Live UI 的理念高度契合。
2. HTML 完全干净且符合标准
Rock
- 没有奇怪的标签、繁重的自定义属性或脏的标记。
后果
- SEO 友好
- 渐进增强
- 与前端工具完全兼容
3. 游戏逻辑完全不使用任何 JS
- 在许多现代框架中,JavaScript 很重,或需要 WebAssembly,或需要复杂的构建流水线。
- 在这里 所有游戏逻辑都在 C# 中,UI 只是一个监听器。
这正是许多人一直在寻找的关键点。
4. 注释中的 DSL —— 意想不到且聪明的做法
- 没有 JSON,没有内联脚本,没有数据块。
- 仍然 可解析、安全、缓存友好,并且对浏览器不可见。
该设计展现了对技术的深思熟虑的整体方法。
