常见的客户端 Web 技术

小窍门

此内容摘自电子书、使用 ASP.NET Core 和 Azure 构建新式 Web 应用程序,可在 .NET Docs 上获取或作为可脱机阅读的免费可下载 PDF。

架构现代 Web 应用程序:使用 ASP.NET Core 和 Azure 的电子书封面缩略图。

“网站应该从内外看起来不错。 - 保罗·库克森

ASP.NET 核心应用程序是 Web 应用程序,它们通常依赖于 HTML、CSS 和 JavaScript 等客户端 Web 技术。 通过将页面(HTML)的内容与其布局和样式(CSS)以及其行为(通过 JavaScript)分离,复杂的 Web 应用可以利用关注点分离原则。 当这些问题不相互交织时,可以更轻松地更改应用程序的结构、设计或行为。

虽然 HTML 和 CSS 相对稳定,但 JavaScript(通过使用应用程序框架和实用工具开发人员处理以构建基于 Web 的应用程序)的速度发展迅速。 本章介绍 Web 开发人员使用 JavaScript 的几种方法,并提供 Angular 和 React 客户端库的高级概述。

注释

Blazor 提供 JavaScript 框架的替代方法,用于生成丰富的交互式客户端用户界面。

HTML

HTML 是用于创建网页和 Web 应用程序的标准标记语言。 其元素构成页面的构建基块,表示格式化文本、图像、表单输入和其他结构。 当浏览器向 URL 发出请求(无论是提取页面还是应用程序)时,返回的第一件事是 HTML 文档。 此 HTML 文档可以引用或包含有关其外观和布局的其他信息(以 CSS 的形式)或 JavaScript 形式的行为。

CSS

CSS (级联样式表)用于控制 HTML 元素的外观和布局。 CSS 样式可以直接应用于 HTML 元素,在相同的页面上单独定义,也可以在单独的文件中定义并由页面引用。 样式根据用于选择给定 HTML 元素的方式进行级联。 例如,样式可应用于整个文档,但会由应用于特定元素的样式覆盖。 同样,特定于元素的样式会由应用于 CSS 类的样式(曾应用于该元素)覆盖,后者反过来会由指向该元素的特定实例(通过其 ID)的样式覆盖。 图 6-1

CSS 特定性规则

图 6-1. CSS 特定性规则按顺序排列。

最好将样式保存在自己的单独的样式表文件中,并使用基于选择的级联在应用程序中实现一致且可重用的样式。 应避免在 HTML 中放置样式规则,并将样式应用于特定的单个元素(而不是整个元素类,或者应用了特定 CSS 类的元素)应该是例外,而不是规则。

CSS 预处理器

CSS 样式表缺乏对条件逻辑、变量和其他编程语言功能的支持。 因此,大型样式表通常包含相当多的重复,因为相同的颜色、字体或其他设置应用于 HTML 元素和 CSS 类的许多不同的变体。 CSS 预处理器可以通过添加对变量和逻辑的支持来帮助样式表遵循 DRY 原则

最常用的 CSS 预处理器是 Sass 和 LESS。 扩展 CSS 并与其向后兼容,这意味着普通 CSS 文件是有效的 Sass 或 LESS 文件。 Sass 基于 Ruby,LESS 是基于 JavaScript 的,通常都作为本地开发过程的一部分运行。 两者都有可用的命令行工具,以及 Visual Studio 中的内置支持,用于使用 Gulp 或 Grunt 任务运行它们。

Javascript

JavaScript 是一种动态解释的编程语言,已在 ECMAScript 语言规范中标准化。 它是 Web 的编程语言。 与 CSS 一样,JavaScript 可以定义为 HTML 元素中的属性、页面内的脚本块或单独的文件中。 与 CSS 一样,建议将 JavaScript 组织到单独的文件中,尽可能将其与单个网页或应用程序视图中的 HTML 分开。

在 Web 应用程序中使用 JavaScript 时,通常需要执行以下几个任务:

  • 选择 HTML 元素并检索和/或更新其值。

  • 查询 Web API 以获取数据。

  • 向 Web API 发送命令(并使用其结果响应回叫)。

  • 执行验证。

可以单独使用 JavaScript 执行所有这些任务,但存在许多库来简化这些任务。 其中第一个和最成功的库之一是 jQuery,它仍然是简化网页上这些任务的热门选择。 对于单页应用程序(SPA),jQuery 不提供 Angular 和 React 提供的许多所需功能。

使用 jQuery 的旧 Web 应用

尽管 JavaScript 框架标准很古老,但 jQuery 仍然是一个常用的库,用于处理 HTML/CSS 并构建对 Web API 进行 AJAX 调用的应用程序。 但是,jQuery 在浏览器文档对象模型(DOM)级别运行,默认情况下仅提供命令性模型而不是声明性模型。

例如,假设文本框的值超过 10,则应使页面上的元素可见。 在 jQuery 中,通常可以通过编写包含代码的事件处理程序来实现此功能,该处理程序将检查文本框的值,并基于该值设置目标元素的可见性。 此过程是基于代码的命令性方法。 另一个框架可能会改用数据绑定技术,将元素的可见性以声明方式绑定到文本框的值。 此方法不需要编写任何代码,而只需要修饰数据绑定属性所涉及的元素。 随着客户端行为变得越来越复杂,数据绑定方法通常会导致代码和条件复杂性降低的更简单的解决方案。

jQuery 与 SPA 框架

因素 jQuery
抽象 DOM 是的 是的
AJAX 支持 是的 是的
声明性数据绑定 是的
MVC 样式路由 是的
模板化 是的
深层链接路由 是的

通过添加其他库可以添加 jQuery 本身缺少的大多数功能。 但是,Angular 等 SPA 框架以更集成的方式提供这些功能,因为它从一开始就设计了所有这些功能。 此外,jQuery 是一个命令性库,这意味着你需要调用 jQuery 函数才能使用 jQuery 执行任何作。 SPA 框架提供的很多工作和功能都可以以声明方式完成,无需编写任何实际代码。

数据绑定是此功能的一个很好的示例。 在 jQuery 中,它通常只需要一行代码来获取 DOM 元素的值或设置元素的值。 但是,每当需要更改元素的值时,必须编写此代码,有时这发生在页面上的多个函数中。 另一个常见示例是元素可见性。 在 jQuery 中,你可能会在许多不同的位置编写代码来控制某些元素是否可见。 在每种情况下,使用数据绑定时,无需编写任何代码。 只需将有关元素的值或可见性绑定到页面上的 viewmodel ,并且对该 viewmodel 的更改将自动反映在绑定元素中。

Angular SPA

Angular 仍然是世界上最受欢迎的 JavaScript 框架之一。 自 Angular 2 以来,团队从头开始重新生成框架(使用 TypeScript),并将原始 AngularJS 名称重新命名为 Angular。 重新设计已有几年的 Angular 仍然是构建单页应用程序的可靠框架。

Angular 应用程序是从组件生成的。 组件将 HTML 模板与特殊对象组合在一起,并控制页面的一部分。 Angular 文档中的简单组件如下所示:

import { Component } from '@angular/core';

@Component({
    selector: 'my-app',
    template: `<h1>Hello {{name}}</h1>`
})

export class AppComponent { name = 'Angular'; }

组件是使用 @Component 修饰器函数定义的,该函数采用有关组件的元数据。 选择器属性用于标识将在页面上显示此组件的元素的 ID。 模板属性是一个简单的 HTML 模板,其中包含与组件的名称属性对应的占位符,该属性在最后一行中定义。

通过使用组件和模板(而不是 DOM 元素),Angular 应用可以在更高级别的抽象下运行,并且整体代码比仅使用 JavaScript(也称为“vanilla JS”)或 jQuery 编写的应用少。 Angular 还对如何组织客户端脚本文件施加了某种顺序。 根据惯例,Angular 应用使用通用文件夹结构,以及位于应用文件夹中的模块和组件脚本文件。 与生成、部署和测试应用相关的 Angular 脚本通常位于更高级别的文件夹中。

可以使用 CLI 开发 Angular 应用。 在本地开始使用 Angular 开发(假设您已安装 git 和 npm),只需从 GitHub 克隆存储库并运行 npm installnpm start。 除此之外,Angular 还提供了自己的 CLI,它可以创建项目、添加文件以及协助测试、捆绑和部署任务。 此 CLI 友好性使 Angular 与 ASP.NET Core 特别兼容,它还具有出色的 CLI 支持。

Microsoft开发了一个引用应用程序 eShopOnContainers,其中包括 Angular SPA 实现。 此应用包括 Angular 模块,用于管理在线商店的购物篮、从其目录中加载和显示项目以及处理订单创建。 可以从 GitHub 查看和下载示例应用程序。

反应

与 Angular 不同,它提供完整的模型View-Controller 模式实现,React 只关注视图。 它不是一个框架,只是一个库,所以要构建 SPA,你需要利用其他库。 有许多库设计用于 React 来生成丰富的单页应用程序。

React 最重要的功能之一是它使用虚拟 DOM。 虚拟 DOM 提供了几个优点,包括性能(虚拟 DOM 可以优化实际 DOM 需要更新哪些部分)和可测试性(无需浏览器测试 React 及其与虚拟 DOM 的交互)。

React 在如何与 HTML 配合使用方面也很特别。 React 不会将代码和标记严格区分(可能以 HTML 属性形式引用 JavaScript),而是将 HTML 直接作为 JSX 添加到其 JavaScript 代码中。 JSX 类似于 HTML 的语法,可以编译为纯 JavaScript。 例如:

<ul>
{ authors.map(author =>
    <li key={author.id}>{author.name}</li>
)}
</ul>

如果你已经知道 JavaScript,学习 React 应该很容易。 与 Angular 或其他流行库相比,其学习曲线和特殊语法并没有那么复杂。

由于 React 不是完整的框架,因此通常希望其他库处理路由、Web API 调用和依赖项管理等作。 好的是,你可以为每个库选择最好的库,但缺点是,你需要做出所有这些决定,并在完成后验证所有所选库协同工作。 如果需要良好的起点,可以使用 React Slingshot 等初学者工具包,它将一组兼容的库预打包到 React 中。

Vue

从其入门指南中,“Vue 是用于生成用户界面的渐进式框架。 与其他整体框架不同,Vue 从头开始设计为可增量采用。 核心库仅侧重于视图层,易于选取并与其他库或现有项目集成。 另一方面,当与新式工具和支持库结合使用时,Vue 完全能够为复杂的 Single-Page 应用程序提供支持。

Vue 入门只需在 HTML 文件中包括其脚本:

<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

添加框架后,可以使用 Vue 的直接模板语法以声明方式将数据呈现到 DOM:

<div id="app">
  {{ message }}
</div>

然后添加以下脚本:

var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})

这足以在页面上呈现 "Hello Vue!" 。 但是,请注意,Vue 不只是将消息呈现给 div 一次。 它支持数据绑定和动态更新,因此如果message的值改变,<div>的值会立即更新以反映这一变化。

当然,这只是 Vue 功能的冰山一角。 在过去的几年里,它获得了很大的受欢迎程度,并拥有一个庞大的社区。 有一个庞大且不断增长的组件和库列表,这些都支持 Vue,并可用于扩展其功能。 如果要将客户端行为添加到 Web 应用程序或考虑生成完整的 SPA,Vue 值得调查。

Blazor WebAssembly

与其他 JavaScript 框架不同,是一个单页应用(SPA)框架, Blazor WebAssembly 用于使用 .NET 生成交互式客户端 Web 应用。 Blazor WebAssembly 使用开放 Web 标准,无需插件或将代码重新编译为其他语言。 Blazor WebAssembly 适用于所有新式 Web 浏览器,包括移动浏览器。

WebAssembly(缩写 wasm)可以在 Web 浏览器中运行 .NET 代码。 WebAssembly 是针对快速下载和最大执行速度优化的压缩字节码格式。 WebAssembly 是一种开放 Web 标准,在 Web 浏览器中不受插件支持。

WebAssembly 代码可以通过 JavaScript(称为 JavaScript 互作性)访问浏览器的完整功能,通常缩短为 JavaScript 互作或 JS 互作。 通过浏览器中的 WebAssembly 执行的 .NET 代码在浏览器的 JavaScript 沙盒中运行,沙盒提供的保护可防御客户端计算机上的恶意操作。

有关详细信息,请参阅 ASP.NET Core Blazor简介

选择 SPA 框架

在考虑哪种选项最适合支持 SPA 时,请记住以下注意事项:

  • 你的团队是否熟悉框架及其依赖项(在某些情况下包括 TypeScript) ?

  • 框架有多固执己见,你是否同意它的默认执行方式?

  • 它(或配套库)是否包含应用所需的所有功能?

  • 记录得很好吗?

  • 其社区有多活跃? 是否正在用它构建新项目?

  • 其核心团队有多活跃? 是否解决了问题并定期发布新版本?

框架以惊人的速度不断发展。 使用上面列出的注意事项来帮助降低选择框架时的风险,以免你以后可能会后悔选择依赖某框架。 如果你特别反风险,请考虑提供商业支持和/或由大型企业开发的框架。

参考 – 客户端 Web 技术