URL 缩短器是我们用来使链接比实际长度更短的工具。使用 URL 缩短器,您可以将一个长链接(可能是注册表单或文章的链接)转换为较短的版本。
在幕后,给定链接的长版本和短版本都存储在某个数据库中。然后,当用户在浏览器中访问短链接时,URL 缩短器会将用户重定向到链接的长版本(即实际内容所在的位置)。
URL 缩短器生成的缩短链接通常用于链接的长版本过长而无法使用的情况。在社交媒体上分享链接或在设计传单和广告时,URL 缩短器非常常用。
在我的一个项目中,我创建了一个个人 URL 缩短器。我的目的是将其用于我撰写的文章或制作的视频的链接。我使用了 Firebase 构建 URL 缩短器的后端。具体来说,我使用了 Firestore 数据库来存储任何给定链接的短版本和长版本。
要创建链接,我必须使用 Firebase 控制台。这并不是问题,但对于频繁编辑链接来说,操作起来比较繁琐。用户体验 (UX) 并不理想。现在我面临着一个问题:如何创建、编辑和删除链接?我需要为 URL 缩短器构建一个前端。我需要一个网站来实现这一点。
在本文中,我们将回顾构建此前端时可用的工具、决策选择以及影响这些决策的因素。
问题陈述
项目需求包括:
- 平台/架构。编码过程的工程和结构。
- UI 工具包。用于 UI 各个部分的组件。
- 便利性。构建后端并不困难,因此前端也不应该困难。我想要简洁的代码和快速的开发。
第一个决策选择:Angular
在开始构建前端时,许多想法会涌上心头。从广义上讲,我们可以将前端构建选项分为 3 个平台:
- 网站构建器 – 如 WordPress、Wix、Squarespace 等。
- 原生构建 – 使用纯 HTML、CSS 和 JavaScript。
- JavaScript 框架 – 如 React、Vue、Angular 等。
根据我的经验,网站构建器提供的组件、模板和小部件集合非常有限。大多数网站构建器都没有提供一种简单的方法来集成像 Firebase 这样的完整自定义后端。虽然可以通过将这些部分连接在一起构建出令人印象深刻的网站,但我的项目的复杂程度可能超出了这些服务通常提供的范围。
使用无框架样式或原生方式也是一种可能性。但是,让我没有选择纯原生路线的决定性因素是 Firebase JavaScript SDK(版本 9)的最新非 CDN 版本 旨在通过 npm
或 yarn
安装以及模块捆绑。
JavaScript 框架处理前端核心部分(如路由、后端链接等)以减少开发人员的工作量。它们有很多,选择使用哪一个似乎是一个更难做出的选择。
有很多 JavaScript 框架可用于前端开发。例如 Angular、React、Vue 等。
在可用的框架中,我对 Angular 最熟悉。因为我在之前的项目中使用过它,例如:
- 圣歌颂歌测验:一个门户网站,参与者在其中参加了两轮关于所选圣经章节的限时选择题在线竞赛。
- Genesys AE-FUNAI 社区:一个自定义表单,Genesys 校园俱乐部 AE-FUNAI(我的社区)的成员可以在其中报告他们的进度并分享他们的成就。
- 教程管理系统:学生和导师之间简单的会话管理仪表板。
这种熟悉度让我能够快速使用 Angular 构建。能够快速构建这一点不容忽视。
我选择 Angular 是因为它具有面向对象编程 (OOP) 的能力。OOP 是一种编程范式,它更关注类、数据或状态的管理,而不是像函数式编程那样关注控制数据的逻辑。关注点分离是使用 OOP 的一个优势。换句话说,OOP 允许封装。它允许您将程序的各个方面限定到特定的域或类。
在 Angular 中,组件(及其生命周期方法)被限定到 TypeScript 类。这会让你以 OOP 的方式思考。OOP 的优势体现在 Angular 组件如何在 Angular 框架中充当可重用的 UI 单位。这样你就将 Angular 组件视为一个自包含的实体,同时又是整体的一部分。这使得前端开发变得更容易,因为前端应用程序的各个部分可以被限定到组件,因此可以在需要的地方使用。
我还选择 Angular 是因为它使用 TypeScript。TypeScript 是具有类型化编程语言特性的 JavaScript。在此上下文中,类型化意味着变量在其整个生命周期中都不能更改其保存的值的类型。例如,保存字符串的变量在程序中使用时不会突然保存数字。类型化提高了代码质量并减少了错误。
由于其类型系统,TypeScript 减少了调试 Angular 应用程序所花费的时间。它提升了开发人员的体验,因为开发人员将有更多时间来构建前端应用程序。调试对于开发人员来说也变得更容易。
注意:此处详细介绍了使用 TypeScript 进行面向对象编程
仍然,关于 Angular 的优势,Angular 应用程序作为一个完整的设置提供。它们自己处理重要的功能,例如捆绑 CSS 预处理器或 Angular 服务。也就是说,当使用 Angular 时,您不需要独立配置每个库,Angular 会自行处理。
Angular 服务是 Angular 用于配置依赖注入的内容。简单来说,依赖注入是在不需应用程序关心依赖项是如何获取的情况下,为应用程序提供其运行所需的内容(依赖项)。我还选择 Angular 是因为其开箱即用的服务处理能力。例如,Firebase 会自动提供给所有需要它的 Angular 组件,无需任何额外的配置。
面向对象编程、TypeScript 和依赖注入的优势使 Angular 成为前端开发的首选。再加上我之前已经熟悉 Angular 的事实,Angular 对于这个 URL 缩短器项目来说更方便。
CSS-Tricks 上的 Angular 文章 也是故事的一部分。它们让我对使用 Angular 更有信心。
第二个决策选择:Material Design
在选择 Angular 之后,我的下一个任务是考虑如何处理用户界面 (UI)。
我可以忽略它并改用原生 CSS,但为什么要重新发明轮子呢?毕竟,这会违背使用 JavaScript 框架的初衷——便利性。
在选择 UI 工具包时,似乎有很多选择。仅举几例,可以使用 Bootstrap、Bulma、Semantic UI、Tailwind 等。每个工具包都有自己的规范和动机。
对于我的项目的用例,Material Design 处于领先地位。
最重要的因素之一是对 Angular 和 Material Design 的支持。在 material.angular.io
(作为 Angular 文档本身的子域)上有一个专门针对 Angular 的 Material 规范。
我选择 Material Design 是因为它专注于组件。与其他 CSS 框架不同,它没有 CSS 实用程序类。这没关系,因为我只想要一些组件套件(按钮、图标、输入、侧边栏、Snackbar 等)。Material 还自己添加了动画、波纹和阴影效果,使其比其他库更方便。
此外,Angular Material 具有开箱即用的主题支持,在初始化 Angular Material 时,您可以选择为整个 Angular 应用程序选择预定义主题或创建自定义主题。

为了方便起见,我在设置 Angular Material 时选择了一个深色主题。
第三个决策选择:Reactive Forms
在确定了框架和工具包之后,我将注意力转向了 URL 缩短器最重要的功能之一。URL 缩短器前端的核心是用于创建和更新链接的表单。
让我们将此表单称为链接编辑器。链接编辑器表单只有两个输入,一个用于链接的短版本,另一个用于短版本将重定向到的完整 URL。
对于管理表单,Angular 提供了两种机制。因此,您不必像在原生 HTML 和 JavaScript 中那样创建表单并处理其验证和提交,而是必须使用 Angular 提供的两种方式之一。这两种方法是:
- 模板驱动表单
- Reactive Forms
模板驱动表单顾名思义,涉及 HTML(模板)代码控制 Angular 表单的大部分内容。当您的表单功能不多或仅用于一次性使用时,此方法更可取。
另一方面,响应式表单提供了一种模型驱动的表单输入处理方法,这些输入的值会随着时间推移而变化。我需要响应式表单,因为它是我将在任何时间点用来编辑不同链接的相同表单。
此时,之前选择的优势开始发挥作用。Angular Material 具有form-field
组件。form-field
将输入包装为组件,并在必要时提供动画、波纹效果和错误消息。

因此,我将其用于编辑器表单的两个输入。
第四个决策选择:Angular Material 底部表单和抽屉
最终的决策涉及如何改进用户体验。URL 短网址生成器需要其他功能,例如查看所有创建的链接及其分析。这些功能需要屏幕上的空间,这需要我重新考虑是否还有更好的解决方案来向用户显示链接编辑器表单。
如果用户目前不需要链接编辑器表单,那么链接编辑器表单不总是可见是有意义的。这将释放 UI 上的空间用于其他元素。
但是,将这种用户体验拆分为两个独立的页面感觉会造成干扰。相反,为了在需要时打开链接编辑器,我在页面上添加了一个用于创建链接的浮动操作按钮。单击时,该按钮将导致编辑器表单在任何合适的 UI 组件中打开。
顾名思义,底部表单是从屏幕底部打开的 UI 组件。它具有用户可以交互的内容。它覆盖了移动屏幕的当前视图(但不会完全阻止它)。

如果用户将花费大量时间与内容交互,则通常使用底部表单代替弹出窗口。因此,底部表单非常适合在移动屏幕上打开编辑器。但是,当屏幕较宽时,与底部表单交互很困难。我需要一个不同的 UI 组件来在宽屏上显示链接编辑器表单。
抽屉从侧面打开。使用抽屉在宽屏上打开链接编辑器表单是最佳选择。抽屉不适合在移动屏幕上使用编辑器。屏幕宽度相对较小,抽屉可能会完全遮挡屏幕(这不是理想的用户体验)。

我从 Material Design 中选择了这两个 UI 组件,以便表单具有一定的响应式效果。因此,无论是在我的手机还是笔记本电脑上创建链接,都将在合适的 UI 组件中完成。
在代码中,Angular 检查设备的屏幕宽度是否较小。如果是,则打开一个包含链接编辑器表单的底部表单。另一方面,如果屏幕较宽,则 Angular 会打开一个包含相同表单的抽屉。
使用这两个组件带来了一个小的复杂问题。如果我的手机旋转或我的笔记本电脑浏览器窗口的宽度减小,则表单将在相反的 UI 组件中打开。也就是说,它不会在笔记本电脑的抽屉中打开,而是会在底部表单中打开(因为浏览器宽度减小了)。
维护、未来防护、未来版本
当我想到迭代这个项目的机会时,我遇到了当前用例设计的限制,该用例旨在支持单个管理员。但是,通过身份验证和用户帐户,它可以支持其他用户管理链接和访问分析。
在这种情况下,上述组件选择仍然适用。链接编辑器是响应式的,因此在任何设备上,用户都将拥有良好的用户体验。
如果让我重新开始,我想我会尝试一下原生方法。在没有任何帮助程序(如 Angular、Material 或 UI 组件)的情况下完全构建。我会尝试从头开始使用 HTML、CSS 和 JavaScript 构建,看看我是否像我想的那样失去了便利性。
结论
您可以在 GitHub 上访问最终的 Angular 代码。
这是对我在开发项目时做出的一些主要选择进行的回顾。当然,构建 URL 短网址生成器的前端还有更多内容。但首先,这些 UI 组件使构建过程变得便捷。它们使链接编辑器表单具有响应性,并且可以在您的项目中(不一定是 URL 短网址生成器)发挥类似的作用。
您可以使用来自各种库的许多其他 UI 组件用于任何此类项目。但与我的情况一样,如果便利性是决定因素,那么您将做出适合 UI 的正确决策。
最终,塑造我决策的是理解我的项目需要什么、了解我从以前项目中使用过的工具以及对时间限制的预期。我过去的经验——成功和错误——也帮助指导了我。
干杯!
Angular 已停止维护。
https://blog.angular.io/discontinued-long-term-support-for-angularjs-cc066b82e65a
嗨,Jens,
让我们重新表达一下。
AngularJS 已停止维护。
Angular 和 AngularJS 之间存在差异。
区别在于 Angular(我用来构建 URL 短网址生成器的框架)是作为完全独立且改进的框架开发的现代版本,与 AngularJS 不同。AngularJS 是最初的第一个版本,其工作方式与我们现在简单称为 Angular 的第二个版本非常不同。
启动 AngularJS 的同一位 Google 工程师在它仍然处于版本 1 时发现了它的一些问题,然后为版本 2 创建了一个不同的框架。为了保持支持并使事情清晰,他们将新的框架命名为 Angular(末尾没有 JS)。
Angular 完全使用 TypeScript。
查看此链接以了解 Angular 和 AngularJS 之间的差异
我知道这有点令人困惑,但停止维护的是 AngularJS,而不是 Angular。您发布的链接中甚至提到了这一点:“我们鼓励团队将其应用程序升级到 AngularJS 的继任者 Angular”。这篇文章是关于 Angular 的。
嗯,这完全不正确。Angular.js 是一个古老的(以开发人员年为单位)产品,早于 React。它与 Angular 不同,Angular 是作者正在使用的框架。
Angular.js 已经不再受支持。
Angular 运行良好,每年发布两次或更多次主要版本
https://github.com/angular/angular/releases
作者使用 Angular,但您指的是 Angular JS,它们是两个独立的框架。前者是后者的演变。
该博客文章仅关于 AngularJS,Angular 的第一个版本与之后的每个版本都大不相同。Angular 本身仍然非常活跃——版本 14 就在上个月发布。
https://blog.angular.io/angular-v14-is-now-available-391a6db736af
AngularJS 已停止维护,它是该框架的原始版本,但 Angular 仍在继续(Obumuneme 在这里谈到的更新且更新的框架版本)。
您链接的文章提到他们希望人们从 AngularJS 迁移到 Angular。
您可以将整篇文章概括为这句话。您为绝对最简单的应用程序选择了绝对最重的框架。然后文章的其余部分是您在假设它是正确选择的情况下为 Angular 做广告……而您完全没有与其他框架进行比较。您查看了您最熟悉的工具,然后倒退着解释为什么它们是这项工作的正确工具,而它们显然是错误的选择。
这不是进行深思熟虑的比较的方式。这是一个选择工具的糟糕模型。我希望没有人将这篇文章作为建议。
更不用说您在假设原生应用程序无法利用模块的基础上进行操作。这是一个使用 TypeScript 构建出色的原生应用程序并快速构建的命令,它是您所需内容的绝佳起点。
npm create vite@latest my-app -- --template vanilla-ts
如果您仍然真的想要 Material,它们以 Web Components 的形式存在。
https://npmjs.net.cn/package/material-components-web
如果您在开始项目或撰写本文之前进行过哪怕是最少的研究,您可能也知道这一点。很抱歉这么苛刻,但您在这里做得不好。
我完全同意,这篇文章的作者没有做太多研究,只是坚持熟悉的路子,并围绕它进行论证。这本身并没有错,但应该在文章中明确说明。
作者和任何阅读本文的人也应该知道,依赖项捆绑不是任何 UI 框架的直接责任。如今我们有 Vite、Snowpack、Parcel,甚至 Webpack 可以与原生 JS 或 TS 一起使用。Web 开发不是靠魔法运行的,它是使用工具构建的,每个人都应该了解他们的工具。
看起来您不需要任何框架来显示一个包含两个字段的表单以及提交后来自服务器的响应。
无需向客户端发送数百千字节的 JavaScript 来解决这个简单的任务。
是的,如果只是两个表单字段,您不需要以上所有内容。
但网址缩短器不仅仅是表单字段,我提到了。诸如分析、身份验证、链接版本历史记录、更新和删除链接、管理域名等功能,使用框架比使用原生方法更好。因此,最好在项目的早期做出选择。
@Jens Törnell AngularJS,而不是 Angular。
@Obumuneme Nwabude
我认为没有理由在现代 JS 框架上选择 Angular(如果您不想使用原生版本)。即使它不是最冗长、最慢和最难使用的——它也是最古老的。而且旧代码和模式几乎总是比新代码和模式更糟糕。
React 是 Angular 的改进版,Vue 是 React 的改进版,而 Svelte 则完全碾压它们。
您可以在此处比较主要 JS 框架的实际组件代码
https://component-party.dev/