JavaScript 框架在现代 Web 前端开发中扮演着重要角色。在开发 Web 项目时,公司会出于多种原因选择框架,包括最终产品的质量、开发成本、编码标准和开发便利性。因此,学习使用 JavaScript 框架(如 Vue)对于任何现代 Web 开发者(或前端开发者或全栈开发者)都是至关重要的。
本书适用于希望使用 Vue 库从头到尾开发 Web 应用程序的程序员,使用 JavaScript 和 TypeScript。它专注于 Vue 及其生态系统如何帮助您在最简单和最舒适的方向上构建可伸缩和交互式 Web 应用程序。在介绍基础知识的同时,我们还将深入 Vue Router 和 Pinia 用于状态管理、测试、动画、部署和服务器端渲染,确保您可以立即开始开发复杂的 Vue 项目。
如果您对 Vue 或虚拟 DOM 的概念不熟悉也没关系。本书不假设您具备 Vue 或任何类似框架的任何先验知识。我将从零开始介绍和引导您了解 Vue 的基础知识。在第二章中,我还将为您讲解 Vue 中的虚拟 DOM 概念和响应系统,作为本书其余部分的基础。
本书不要求您了解 TypeScript,但如果您熟悉 TypeScript 基础,则会更有准备。如果您事先掌握了 HTML、CSS 和 JavaScript 的基础知识,那么您也将更好地准备好阅读本书的内容。在深入任何网络(或前端)JavaScript 框架之前,这三者的扎实基础始终至关重要。
本书旨在帮助您完成工作。一般来说,如果本书提供示例代码,您可以在程序和文档中使用它。除非您复制了代码的大部分,否则无需获得我们的许可。例如,编写一个程序使用本书中几个代码块不需要许可。出售或分发奥莱利书籍中的示例需要许可。引用本书并引用示例代码回答问题不需要许可。将本书的大量示例代码整合到您产品的文档中需要许可。
我们独特的专家和创新者网络通过书籍、文章和我们的在线学习平台分享他们的知识和专业知识。奥莱利的在线学习平台为您提供按需访问的实时培训课程、深入学习路径、交互式编码环境以及来自奥莱利和其他 200 多个出版商的广泛文本和视频资源。更多信息,请访问 http://oreilly.com。
在撰写这本书的旅程中,我的家庭正经历着动荡不安的时期,充满高低起伏。尽管享受每一个时刻,但写作这本书需要大量的时间、精力和奉献精神。没有家人的支持,特别是我的丈夫 Natan 的支持,我无法全身心投入其中。他对我的编程能力的鼓励和信任,在前端开发方面的幽默感,以及在我工作出差期间帮助照顾孩子、倾听我的日常怨言、帮助我平衡工作和个人生活的支持,都是无价的。没有 Natan,我今天不会有现在的成就。
就像优质的代码需要彻底审查一样,这本书的卓越之处很大程度上归功于 Jakub Andrzejewski、Chris Fritz、Lipi Patnaik、Edward Wong 和 Vishwesh Ravi Shrimali 的关键技术见解和鼓励。你们宝贵的反馈在提升我的专注力和提高这部作品的质量方面起到了关键作用。
特别感谢 Vue 核心团队开发了如此优秀的框架和生态系统,以及 Vue 社区成员和朋友们的支持和启发。我从你们那里获得的知识和见解是无法估量的,且每天都在丰富着我。
Vue.js 最初发布于 2014 年,特别是在 2018 年迅速被广泛采用。Vue 在开发者社区中非常受欢迎,这要归功于其易用性和灵活性。如果您正在寻找一个出色的工具来构建和发布优秀性能的 Web 应用程序给最终用户,Vue.js 就是您的答案。
本章突出介绍了 Vue.js 的核心概念,并引导您了解您的 Vue.js 开发环境所需的工具。它还探讨了使您的 Vue.js 开发过程更加可管理的有用工具。通过本章的学习,您将拥有一个简单的 Vue.js 应用程序的工作环境,准备好开始学习 Vue.js 的旅程。
Vue 基于 JavaScript 编写,并提供了一种组织机制来构建和组织 Web 应用程序。它还作为转译器,在部署前将 Vue 代码(作为单文件组件,我们将在“Vue 单文件组件结构”中进一步讨论)编译和转换为等效的 HTML、CSS 和 JavaScript 代码。在独立模式下(使用生成的脚本文件),Vue 引擎会在运行时执行代码转换。
Vue 的显著优势在于其写作清晰易懂的文档。此外,围绕 Vue 构建的生态系统和支持社区,如 Vue Router、Vuex 和 Pinia,帮助开发者以最小的努力设置和运行其项目。
Vue 的 API 直接明了,对于之前使用过 AngularJS 或 jQuery 的开发者来说非常熟悉。其强大的模板语法最大程度地减少了学习成本,并且使得在应用程序中处理数据或监听文档对象模型(DOM)事件变得更加容易。
Vue 提供的另一个显著优势是其大小。框架的大小是应用性能的重要因素,特别是交付时的初始加载时间。在撰写本文时,Vue 是最快和最轻量级的框架(约 10kB 的大小)。这一优势导致下载时间较短,并从浏览器的角度提供更好的运行时性能。
Node.js(或 Node)是建立在 Chrome 的 V8 JavaScript 运行时引擎上的开源 JavaScript 服务器环境。Node 允许开发人员在本地或托管服务器上编写和运行 JavaScript 应用程序,而无需浏览器。
Node 包管理器(NPM)是 Node 的默认包管理器。它会随 Node.js 一起安装。它允许开发人员轻松下载和安装其他远程 Node 包。Vue 和其他前端框架是有用的 Node 包的示例。
如果 NPM 是标准的包管理工具,那么 Yarn 是由 Facebook 开发的替代性和流行的包管理器。[³] 由于其并行下载和缓存机制,Yarn 更快速、更安全、更可靠。它与所有 NPM 包兼容,因此可以作为 NPM 的即插即用替代品使用。
Vue 开发者工具(或 Vue Devtools)是官方工具,可帮助您在本地处理 Vue 项目。这些工具包括 Chrome 和 Firefox 的扩展,以及其他浏览器的 Electron 桌面应用程序。您应该在开发过程中安装其中一个工具。
扩展安装并启用后,您可以检测当前是否有任何网站在生产中使用 Vue。当一个站点使用 Vue 构建时,浏览器工具栏上的 Vue 图标将突出显示,如图 1-4 所示。
Vue Devtools 允许您在浏览器的开发者控制台中检查 Vue 组件树、组件 props 和数据、事件以及路由信息。Vue Devtools 将信息分成各种选项卡,为调试和检查项目中任何 Vue 组件的行为提供有益的见解。
Vite.js(或简称 Vite)是一个 JavaScript 开发服务器,于 2020 年推出,开发过程中使用原生 ES 模块^(4) 导入,而不像 Webpack、Rollup 等将您的代码打包成 JavaScript 文件块。
这种方法允许 Vite 在开发过程中以极快的速度进行热重载^(5),使开发体验更加流畅。它还提供许多开箱即用的功能,如对 TypeScript 的支持和按需编译,快速在开发者社区中获得了广泛的认可和适应。
包含将根组件(App.vue)挂载到 DOM 页面上的 TypeScript 代码。此文件还用于在应用程序中设置插件和第三方库,例如 Vue Router、Pinia 等。
在本章中,我们学习了 Vue 的好处以及如何为 Vue 开发环境安装必要的工具。我们还讨论了 Vue 开发者工具和其他有效构建 Vue 项目的工具,例如 Vite。现在我们已经创建了我们的第一个 Vue 项目,准备学习 Vue 的基础知识:Vue 实例、内置指令以及 Vue 如何处理响应性。
^(1) MVC 模式通过将应用程序结构分为 UI(视图)、数据(模型)和控制逻辑(控制器)来帮助实现应用程序。虽然视图和控制器可以进行双向绑定,但只有控制器可以操作模型。
本章介绍了虚拟文档对象模型(Virtual DOM)的概念和使用 Vue 选项 API 编写 Vue 组件的基础知识。它还探讨了更多的 Vue 指令和 Vue 响应性机制。通过本章末尾,您将理解 Vue 的工作原理,并能够编写和注册用于应用程序的 Vue 组件。
DOM 在 Web 上代表 HTML(或 XML)文档内容,以内存中树状数据结构的形式表示(如图 2-1 所示)。它充当一个连接网页和实际编程代码(如 JavaScript)的编程接口。HTML 文档中的标签,例如 <div> 或 <section>,在 DOM 中被表示为编程节点和对象。
浏览器解析 HTML 文档后,DOM 将立即可供交互使用。在任何布局更改时,浏览器会在后台持续地绘制和重绘 DOM。我们称这个过程为解析,而绘制 DOM 屏幕的过程称为光栅化或像素到屏幕流水线。图 2-2 展示了光栅化的工作原理:
在小规模上查询和更新 DOM 通常不会对性能产生巨大影响。但是,如果在更复杂的网页上重复(在几秒钟内)进行这些操作,则可能会减慢页面。当连续进行小更新时,性能影响尤为显著。许多框架,如 Angular 1.x,在代码基础增长时未能认识和解决这个性能问题。虚拟 DOM 的设计目的就是解决布局更新问题。
由于虚拟 DOM 是一组自定义 JavaScript 对象的树,更新组件等同于更新自定义 JavaScript 对象。这个过程不会花费太长时间。因为我们不调用任何 DOM API,所以这个更新动作不会引起 DOM 重绘。
由于虚拟 DOM 是对象树,当修改虚拟 DOM 时,我们可以轻松地跟踪需要与实际 DOM 同步的特定更新。现在,我们不再直接查询和更新实际 DOM,而是可以在一个更新周期中调度和调用更新的 API,并通过单个渲染函数维护性能效率。
双向绑定指的是如何在组件逻辑和视图模板之间同步数据。当组件的数据字段在程序中改变时,新值会反映在其 UI 视图上。反之,当用户在 UI 视图上对数据字段进行更改时,组件会自动获取并保存更新后的值,保持内部逻辑和 UI 的同步。一个很好的双向绑定例子是表单输入字段。
双向数据绑定是应用开发中复杂但有益的用例。双向绑定的一个常见场景是表单输入同步。正确实现可以节省开发时间,并减少在实际 DOM 和组件数据之间维护数据一致性的复杂性。但实现双向绑定是一个挑战。
动态列表渲染对于减少重复代码、增加代码可重用性以及保持类似元素类型组的格式一致性至关重要。例如文章列表、活跃用户和你关注的 TikTok 账号列表。在这些示例中,数据是动态的,而内容类型和 UI 布局保持相似。
在浏览器将事件分派到目标元素之前,它会使用当前 DOM 树结构构建该事件的传播路径列表。此路径的最后一个节点是目标元素本身,前面的节点依次是其祖先。一旦分派,事件将通过一个或所有三个主要事件阶段传播(见图 2-19):
表 2-1. v-on指令的事件修饰符
本章探讨了虚拟 DOM 及其在 Vue 中实现性能目标的方法。我们学习了如何使用 JSX 和函数组件控制组件渲染,处理内置 Vue 指令,并使用它们来处理组件的本地数据以在 UI 模板上进行响应显示。我们还学习了响应性基础知识以及如何使用选项 API 和模板语法创建和注册 Vue 组件。这些是深入理解下一章节中 Vue 组件机制的基础。
在上一章中,您已经学习了 Vue 的基础知识,并使用 Options API 编写了具有常见指令的 Vue 组件。现在,您已经准备好深入探讨下一个层次:使用响应式和钩子组合更复杂的 Vue 组件。
本章介绍了 Vue 单文件组件(SFC)标准、组件生命周期钩子,以及其他高级响应式特性,如计算属性、监听器、方法和引用。您还将学习如何使用插槽来动态渲染组件的不同部分,并保持样式结构。通过本章的学习,您将能够在应用程序中编写复杂的 Vue 组件。
仅当组件的响应式数据发生变化时才相关。在此阶段,Vue 渲染器使用新数据重新渲染组件的 DOM 节点,并执行修补更新。类似于挂载阶段,更新过程以子元素优先,然后是组件本身结束。
Vue 渲染器从 DOM 中分离组件并销毁实例及其所有响应式数据效果。此阶段是生命周期的最后阶段,在应用程序中不再使用组件时发生。类似于更新和挂载阶段,组件只能在其所有子组件卸载后自行卸载。
表 3-1. 为合适的目的使用合适的钩子
方法有助于保持组件逻辑的组织性。Vue 仅在相关时触发方法(例如在模板中调用,如示例 3-9 中所示),允许我们动态地从本地数据计算新的数据值。然而,对于方法,Vue 不会缓存每次触发的结果,并且每次重新渲染时都会重新运行该方法。因此,在需要计算新数据的场景中,最好使用计算属性,接下来我们将进行探讨。
使用计算属性有助于将复杂数据修改组织为可重用的数据块。因此,它减少了所需的代码量并保持代码清晰,同时提高组件的性能。使用计算属性还允许您快速设置任何响应式数据属性的自动观察器,方法是将它们出现在计算属性函数的实现逻辑中。
您可以直接将处理程序函数分配给观察器名称。Vue 引擎将自动使用一组默认配置调用处理程序。但是,您也可以将对象传递给观察器的名称,以自定义观察器的行为,使用表 3-2 中的字段。
表 3-2. 观察器对象的字段
构建组件不仅涉及其数据和逻辑。我们经常希望保持当前组件的感觉和现有设计,但仍然允许用户修改 UI 模板的部分。在任何框架中构建可定制组件库时,这种灵活性至关重要。幸运的是,Vue 提供了 <slot> 组件,允许我们在需要时动态替换元素的默认 UI 设计。
这就是全部。现在您已经准备好使用插槽来自定义您的 UI 组件了。使用插槽,您现在可以为应用程序创建一些基本的标准可重复使用的布局,例如带有页眉和页脚的页面布局,侧边栏布局,或者可以是对话框或通知的模态组件。然后,您将发现插槽在保持代码组织和可重用性方面是多么方便。
虽然 Vue 通常会为您处理大部分 DOM 交互,但在某些场景中,您可能需要直接访问组件内的 DOM 元素以进行进一步操作。例如,当用户点击按钮时要打开模态对话框,或者在组件安装时聚焦特定输入字段。在这种情况下,您可以使用 ref 属性来访问目标 DOM 元素实例。