Vue.js全平台前端实战

978-7-115-58390-1
作者: 凌杰
译者:
编辑: 郭媛

图书目录:

详情

近十年来前端应用市场的规模日益扩张,学习前端开发及其框架的应用已经成为众多开发者在职业生涯中必须要面对的课题之一。 本书将以Vue.js 框架及其在移动端的扩展框架uni-app 为中心来探讨如何开发面向同一Web 服务的不同形式的前端。本书内容涵盖Vue.js 2.x/3.x 框架与uni-app 框架的设计理念、适用领域、环境配置方法,以及它们在传统PC 端Web 浏览器、iOS/Android 以及微信/支付宝等小程序平台这些不同前端环境中的具体项目实践。在这些项目的演示过程中,本书将提供大量可读性强、可被验证的代码示例,以帮助读者循序渐进、层层深入地理解前端开发领域所涉及的技术概念、编程思想与框架设计理念。 本书适合对HTML+CSS+JavaScript 技术、HTTP、Web 浏览器中的DOM 和BOM 等基础知识有一定了解,且对Vue.js 及其扩展框架有兴趣的初学者、前端开发人员与设计师阅读。

图书摘要

版权信息

书名:Vue.js全平台前端实战

ISBN:978-7-115-58390-1

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

著    凌 杰

责任编辑 郭 媛

人民邮电出版社出版发行  北京市丰台区成寿寺路11号

邮编 100164  电子邮件 315@ptpress.com.cn

网址 http://www.ptpress.com.cn

读者服务热线:(010)81055410

反盗版热线:(010)81055315

读者服务:

微信扫码关注【异步社区】微信公众号,回复“e58390”获取本书配套资源以及异步社区15天VIP会员卡,近千本电子书免费畅读。


近十年来前端应用市场的规模日益扩张,学习前端开发及其框架的应用已经成为众多开发者在职业生涯中必须要面对的课题之一。本书将以Vue.js框架及其在移动端的扩展框架uni-app为中心来探讨如何开发面向同一Web服务的不同形式的前端。本书内容涵盖Vue.js 2.x/3.x框架与uni-app框架的设计理念、适用领域、环境配置方法,以及它们在传统PC端Web浏览器、iOS/Android以及微信小程序平台等各类不同前端环境中的具体项目实践。在这些项目的演示过程中,本书将提供大量可读性强、可被验证的代码示例,以帮助读者循序渐进、层层深入地理解前端开发领域所涉及的技术概念、编程思想与框架设计理念。

本书适合对HTML+CSS+JavaScript技术、HTTP、Web浏览器中的DOM和BOM等基础知识有一定了解,且对Vue.js及其扩展框架有兴趣的初学者、前端开发人员与设计师阅读。


早在我的上一本书——《JavaScript 全栈开发》的审阅阶段,我就常听到一种反馈观点,这种观点是:如果只使用DOM和BOM接口来编写前端应用,或者只使用Node.js运行平台的原生接口编写后端应用,那么对于大多数开发者来说,这都将是一个编码量巨大,调试和维护非常繁复的工作。诚然,在现实的生产环境中,开发者大多数时候是使用一种被称为应用程序框架的工具来应对具体项目的开发工作的,所以,如何使用应用程序框架确实是一个初学者在掌握了基础知识之后紧接着要解决的问题。

在编程语境中,应用程序框架通常指一套用于解决特定领域问题的编程工具,这些工具往往是存在适用领域边界的。换言之,我们在开发前端应用时要使用适用于前端领域的框架,而在开发后端应用时则要使用适用于后端领域的框架,它们各自可能都需要用大量篇幅来介绍。

于是,作为《JavaScript 全栈开发》关于前端部分的补充,我尝试着撰写了这本以Vue.js框架为工具介绍前端应用开发的书。

本书将致力于探讨在前端领域中如何以Vue.js框架为中心,并搭配uni-app这种对Vue.js进行二次封装的移动端框架来开发同一应用程序的不同形式的前端。本书将从Vue.js框架的基本使用方法开始,循序渐进、层层深入地介绍这一渐进式框架在由传统PC端Web浏览器、iOS/Android以及微信/支付宝等小程序平台所构成的各类型前端环境中开发应用时所需要掌握的开发思路、设计理念。在这个过程中,我将会在书中提供大量可读性高、可被验证的代码示例,以帮助读者理解书中所介绍的技术概念、编程思想与框架设计理念。

除了前导部分(第1章),本书主要有3部分。第一部分(第2~6章)将介绍Vue.js框架核心部分的基本使用方法,包括Vue.js框架本身的设计理念、加载方法、基础语法、核心组件以及项目组织方式等。第二部分(第7~9章)将介绍基于PC端浏览器构建一个功能较为简单的短书评应用程序。这部分将具体介绍如何利用Vue.js框架,以RESTful API为后端服务创建面向PC端浏览器的现代互联网应用程序。第三部分(第10~12章)将介绍基于移动端设备构建一个功能较为简单的短书评应用程序。这部分将具体介绍如何利用对Vue.js框架进行了二次封装的uni-app框架,并以RESTful API为后端服务创建面向移动端的现代互联网应用程序。下面是本书各章的内容简介。

第1章准备工作。本章将会带领读者为本书将要展开的议题讨论和项目实践做一系列准备工作。其中包括构建这些项目所需要了解的预备知识体系、所要使用的编程环境以及使用调试工具所要遵循的基本思路和方法等。

第2章创建前端应用。本章将会对Vue.js框架做简单的介绍,并向读者详细解释本书为什么要选择围绕Vue.js框架来介绍项目的开发实践。此外,本章还将从构建项目目录开始,为读者具体演示如何使用NPM初始化一个Vue.js项目并对其进行配置。

第3章设计用户界面。本章将通过两个简单的示例项目为读者详细介绍Vue.js框架的模板指令,并示范如何使用这些指令来设计用户界面。在掌握了这些知识之后,读者应该就可以完成一些基本的用户界面设计工作。

第4章实现Vue对象。本章将详细介绍Vue对象的定义方式。Vue.js框架的独到之处就是引入了虚拟DOM技术,以便实现Vue对象,并在JavaScript对象与HTML页面之间建立起一套响应式系统。这套响应式系统负责监控Vue对象中发生的数据变化,并即时将变化后的数据更新到HTML页面所定义的用户界面上。

第5章使用Vue组件。本章将重点介绍Vue.js框架中的组件机制。首先介绍自定义组件的基本步骤,为读者示范如何使用webpack打包工具及其相关插件引入定义组件专用的文件格式,这种文件格式将有助于提高开发者基于Vue.js框架来构建项目时的编程效率。接着通过一系列的实验示范在自定义组件中会使用到的一系列模板指令及其相关的机制,以帮助读者掌握设计组件所需要的基本技能。最后,基于“不要重复发明轮子”的原则,为读者示范使用Vue.js框架的内置组件或引用外部组件库来设计用户界面的方法。

第6章使用自动化工具。本章首先会为读者介绍使用自动化工具来构建项目的必要性,并以webpack为例介绍如何使用打包工具对项目中的各类型文件进行转译和压缩处理,并构建出可发布的应用程序。在这个过程中,本章将带读者了解webpack的基本配置选项,以及各类型预处理器和插件的安装和使用方法。最后还将分别演示用Vue CLI脚手架工具构建Vue.js 2.x项目,以及用Vite前端构建工具构建Vue.js 3.x项目的基本步骤。

第7章 构建服务端RESTful API。本章将着重为读者介绍RESTful架构,该架构是一套当前市面上比较适合为Vue.js前端用户界面提供后端服务的解决方案。RESTful架构的主要优势在于它本质上只是一套建立在现有网络协议和通用数据格式之上的设计规范,这意味着,开发者在采用该架构构建后端服务时只需要基于普通的HTTP服务,并遵守这套设计规范即可,无须做太多额外的服务器维护工作。除了对RESTful架构进行概念性介绍,本章还以构建一个短书评应用的后端服务为例,具体介绍RESTful API的设计方法,以及设计过程中需要注意的事项。

第8章 PC端浏览器应用开发(上篇)。本章将开始着重介绍短书评应用在传统PC端Web浏览器上的实现。首先会介绍如何使用Node.js平台来搭建针对Vue.js项目的Web服务。然后,陆续介绍如何利用vue-router组件实现前端应用的多页面路由,如何借助axios这样的第三方网络请求库来调用RESTful API,如何使用Vuex组件实现前端应用的状态管理。

第9章PC端浏览器应用开发(下篇)。本章将接着第8章的内容介绍短书评应用在传统PC端Web浏览器上的基本实现,进一步演示如何在基于Vue.js框架的前端应用中利用vue-router组件实现多视图界面切换,以及如何更进一步利用axios请求库调用后端的RESTful API,从而实现前、后端的数据交互。值得一提的是,由于在这些交互过程中也涉及图片、日期等特殊类型的数据对象,所以本章也将演示这些数据对象的序列化与解析的具体方式。

第10章移动端开发概述。本章将首先介绍移动端应用开发相对于传统PC端Web浏览器上的应用开发所要特别面对的屏幕适配问题和触控响应问题。然后将分别介绍基于HTML5+CSS3技术解决移动端屏幕自动适配问题的响应式设计思路,以及基于HTML5+ES6技术响应触控事件的基本方法,目的是帮助读者了解Vue.js这一类前端框架在底层实现上是如何解决移动端开发所要面对的特殊问题的,以便在后续使用这些框架的过程中“知其然且知其所以然”。接着,本章将会为读者解释为何在众多面向移动端开发的前端解决方案中选择了uni-app这个框架来作为本书演示移动端应用实现的工具。并且,本章还将借助一个由Vue CLI脚手架工具自动生成的示例项目为读者初步介绍一个普通uni-app项目的基本结构及其主要的配置方法。

第11章uni-app项目实践(上篇)。本章将继续以本书第二部分中构建的短书评应用为例,着重为读者演示如何基于uni-app框架来实现移动端的单页面应用。首先会演示如何对一个新建的uni-app项目进行应用程序的全局配置。然后会陆续介绍由uni-app框架提供的常用用户界面组件,并演示如何利用这些组件来设计短书评应用的登录界面。最后还将介绍如何利用uni-app框架的原生接口来调用后端的RESTful API,并对前端应用的本地缓存进行数据管理。

第12章uni-app项目实践(下篇)。本章将接着第11章的内容继续为读者介绍基于uni-app框架创建移动端应用所需要掌握的基础知识。首先将介绍如何使用导航组件标签与页面跳转接口实现应用程序内的多页面跳转,以及如何在执行跳转操作的过程中传递数据。然后将对uni-app框架中为应用实例、页面对象以及组件对象定义的常用生命周期函数做详细的介绍,并简单地演示如何使用这些函数接收来自其他页面的参数,并根据这些参数实现当前页面的数据初始化任务。最后将以HTML5和微信小程序为例,简单演示如何将uni-app项目打包,发布成面向各种具体运行平台的应用程序,真正发挥出uni-app框架“一套代码,多平台发布”的设计优势。

读者须知

由于这是一本专注于介绍如何使用Vue.js框架及其扩展框架开发前端应用的书,而Vue.js是一个基于HTML+CSS+JavaScript技术构建的前端开发框架,因此希望读者在阅读本书之前,已经掌握HTML+CSS+JavaScript技术、HTTP、Web浏览器中的DOM和BOM等相关的基础知识。如有需要,建议读者先阅读本书的前作——《JavaScript全栈开发》,或者其他介绍上述基础知识的书。

除此之外,我在这里还需要特别强调一件事:本书中所有关于短书评应用的实现代码都是基于本书各章节中的代码占比及其阅读体验等众多写作因素进行了平衡考虑之后产生的最简化版本,其中省略了绝大部分与错误处理及其他辅助功能相关的代码。因此,如果想了解实际项目中某些具体问题的解决方案,还需请读者查阅本书附带源码包中的项目。当然,在我个人看来,如果想要学好并熟练掌握一个开发框架,最好的办法就是尽可能地在实践中使用它,在实际项目需求的驱动下模仿、试错并总结使用经验。所以本书并不鼓励读者直接复制/粘贴本书附带源码包中的演示代码,更期待读者“自己动手”去模仿书中提供的示例,亲手将自己想要执行的代码输入计算机,观察它们是如何工作的。然后,试着修改它们,并验证其结果是否符合预期。如果符合预期,就总结当下的经验;如果不符合预期,就去思考应该做哪些调整来令其符合预期。如此周而复始,才能让学习效果事半功倍。

致谢与勘误

本书能够完成,离不开很多人的鼓励和帮助,我在这里需要感谢很多人。如果没有我的好朋友、卷积文化传媒公司的创始人高博先生的提议,我极有可能下不了创作本书的决心。如果没有人民邮电出版社信息技术出版分社的陈冀康社长和郭媛编辑的鼓励和鞭策,我也非常有可能完成不了本书的创作。另外,我还需要感谢我的好友朱磊、范德成、张智宇和陆禹淳,他们都分别对本书的初稿进行了认真的审阅,提供了不少宝贵的建议。最后感谢人民邮电出版社愿意出版这本题材和内容也许没有那么大众化的书,希望本书不会辜负他们的信任。还有,在这里我也需要特别感谢我的家人,感谢你们对我无微不至的照顾和温暖的爱,这些都是我在这个世界上奋斗的动力。

当然,无论如何,本书中都会存在一些不够周全、表达不清的问题。如果读者有任何意见,我都希望你们致信lingjiexyz@hotmail.com,或者在异步社区本书的勘误页面中提出,以帮助我们在本书的后续修订中进一步完善它。

凌 杰

2021年10月


本书由异步社区出品,社区(https://www.epubit.com/)可为您提供相关资源和后续服务。

本书提供如下资源:

本书源码;

本书彩图文件。

要获得以上配套资源,请在异步社区本书页面中单击,跳转到下载页面,按提示进行操作即可。

您还可以扫码右侧二维码, 关注【异步社区】微信公众号,回复“e58390”直接获取,同时可以获得异步社区15天VIP会员卡,近千本电子书免费畅读。

作者和编辑虽然已尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎您将发现的问题反馈给我们,帮助我们提升图书的质量。

当您发现错误时,请登录异步社区,按书名搜索,进入本书页面(见下图),单击“提交勘误”,输入错误信息后,单击“提交”按钮即可。本书的作者和编辑会对您提交的错误信息进行审核,确认并接受后,您将获赠异步社区的100积分。积分可用于在异步社区兑换优惠券、样书或奖品。

扫描下方二维码,您将会在异步社区微信服务号中看到本书信息及相关的服务提示。

我们的联系邮箱是contact@epubit.com.cn。

如果您对本书有任何疑问或建议,请您发邮件给我们,并请在邮件标题中注明书名,以便我们更高效地做出反馈。

如果您有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们;有意出版图书的作者也可以到异步社区在线提交投稿(直接访问www.epubit.com/selfpublish/submission即可)。

如果您所在的学校、培训机构或企业,想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。

如果您在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请您将怀疑有侵权行为的链接发邮件给我们。您的这一举动是对作者权益的保护,也是我们持续为您提供有价值的内容的动力之源。

“异步社区”是人民邮电出版社旗下IT专业图书社区,致力于出版精品IT图书和相关学习产品,为作译者提供优质出版服务。异步社区创办于2015年8月,可提供大量精品IT图书和电子书,以及高品质技术文章和视频课程。更多详情请访问异步社区官网https://www.epubit.com。

“异步图书”是由异步社区编辑团队策划出版的精品IT专业图书的品牌,依托于人民邮电出版社近40年的计算机图书出版积累和专业编辑团队,相关图书在封面上印有异步图书的Logo。异步图书的出版领域包括软件开发、大数据、人工智能、测试、前端、网络技术等。

异步社区

微信服务号


正如前言中所说的,本书将致力于探讨如何在实际项目中以Vue.js框架为中心,搭配uni-app这种对Vue.js进行二次封装的移动设备端(以下简称“移动端”)框架来开发同一应用程序的不同形式的前端。但在开始介绍这一切之前,我们会带领读者完成一些准备工作,以便配备好完善的开发工具,以最好的状态进入后续的知识学习和项目实践。总而言之,在学习完本章之后,希望读者能够:

了解本书所要涉及的技术,以及这些技术被采用的原因;

构建好本书涉及的编程环境,并完成相关工具的配置;

掌握如何使用相关的开发工具进行项目的调试与排错工作。

既然我们已经打算要以Vue.js框架为核心来展开一趟“前端项目开发之旅”,那么首先对该框架所依赖的基础技术应该要有基本的了解,否则就会在一种“不甚了了”的状态下使用该框架来开发应用程序。虽然这种状态通常并不会影响初学者快速上手并开发一些简单的前端项目,但随着项目越做越多,项目中要解决的问题也越来越复杂,终有一天它会成为我们继续进步的瓶颈,到那时候再回过头来补足这些知识并不见得会比初学阶段更容易。所以接下来,我们不妨先花点时间和耐心来简单地了解一下这些基础技术吧[1]

[1] 如果读者已经对这些技术有所了解,可自行跳过本章内容。

从编程方法上来说,无论我们将来基于Vue.js框架构建的是Android/iOS应用程序,还是微信/支付宝小程序,抑或是“纯Web应用程序”,它们在理论上都应被归类为基于客户-服务器(Client-Server,C-S)体系结构的应用程序[2]。在这种体系结构的支持之下,应用程序在部署方式上有了一个全新的选择。开发者可以将应用程序中需要保障数据安全或者进行高速运算的那一部分部署在服务器上,以便享用服务器的高性能配置以及能就近维护的便利。然后根据客户使用的设备或Web浏览器来开发相应的客户端软件,并让它来执行应用程序中需要与用户交互的那一部分任务。这样做既可降低应用程序部署与维护的成本,也可在很大程度上减少应用程序对用户侧的软硬件依赖,同时明确项目开发中的任务分工。

[2] 纯Web应用程序所属的浏览器-服务器(Browser-Server,B-S)体系结构在理论上也是C-S体系结构的一个子集。

所以对于开发者来说,首先要做的就是分清楚应用程序的客户部分与服务器部分在C-S体系结构下各自所承担的任务分工。虽然在手机、手表等移动设备上都能搭载多核处理器的今天,各类型计算设备的性能事实上已经日渐趋同,客户与服务器之间的界线有时候也并非绝对的,但从项目开发与维护的角度来说,做某种程度上的分工安排还是非常有必要的。根据我个人的经验,C-S体系结构之下的任务分工通常是以下这样的。

客户部分在C-S体系结构下所承担的工作主要是与用户进行交互,其角色类似于银行的柜台接待员,所以在术语上往往被称为应用程序的“客户端”或“前端”。在通常情况下,应用程序的前端负责渲染应用程序的用户操作界面、处理用户的操作、向服务器发送请求数据并接收来自服务器的响应数据、维持应用程序的运行状态,以求提供良好的用户体验。这部分的开发与维护在很大程度上依赖于用户所在的软硬件环境。

服务器部分在C-S体系结构下所承担的工作主要是数据的处理和维护,其角色类似于银行金库的管理人员,所以在术语上往往被称为应用程序的“服务端”或“后端”。在通常情况下,应用程序的后端将为用户提供只有大型计算机才具备的运算能力以及安全可靠的数据库服务,它负责存储并处理来自应用程序客户端的请求数据,然后把响应数据返回给客户端,一般用于处理较为复杂的业务逻辑,例如执行与天体物理相关的运算任务、存储海量数据等。这部分的开发和维护通常可以不依赖于用户所在的软硬件环境。

当然,大部分事情都是利弊共存的,C-S体系结构作为一种构建应用程序的解决方案,在享有上述分工优势的同时也是存在着一些劣势的。首先,由于该体系结构在服务端与客户端之间构建的通常是一对多的关系,因此服务端在许多情况下都需要同时处理来自成千上万个客户端的请求,这对服务端设备的负载能力提出了较高的要求,因此维持服务端的稳定性将会成为项目维护阶段的一大难题。其次,采用这种体系结构的应用程序在运行时也会严重依赖于用户所在的网络环境,一旦网络中的某个节点出了问题,例如发生了防火墙屏蔽或域名劫持等情况,整个应用程序可能会立即陷入无法运行的尴尬境地。所以,开发者在使用该体系结构来构建应用程序时必须要做好应对这些劣势的预先安排,例如制定服务器的负载策略、设置备用服务器或备用域名等。

HTML、CSS与JavaScript这3项技术是使用Vue.js框架进行应用程序开发的基础所在,所以它们的基本使用方法也是学习本书的读者必须要事先掌握的预备知识。虽然如前言中所说的,本书将假设读者已经具备了这些知识,但对于HTML、CSS与JavaScript各自在Vue.js项目中所扮演的角色,以及项目所遵循的技术标准、采用的版本,我们在这里依然需要做一些简单的介绍与解释。

1.1.2.1 HTML:定义用户界面的结构

HTML是HyperText Markup Language的英文缩写,在中文里通常被译为“超文本标记语言”,它本质上是一门定义文档结构的标记语言。这门语言的主要作用是将应用程序的用户界面描述成树状的数据结构,以便于Web浏览器或其他客户端框架将其解析成可被JavaScript、VBScript等编程语言直接操作的文档对象模型(Document Object Model,DOM)。例如以下这段HTML代码。

<!DOCTYPE html>
<html lang="zh-cn">
    <head>
        <meta charset="UTF-8">
        <title>浏览器端JS代码测试</title>
    </head>
    <body>
        <h1>浏览器端的JavaScript</h1>
        <div id="content"></div>
    </body>
</html>

Web浏览器或其他客户端框架就会根据它的描述在内存中将其解析成类似图1-1所示的树状数据结构。

接下来,开发者就只需要直接在JavaScript或VBScript代码中对该数据结构进行编程即可。另外需要说明的是,我们在本书的所有项目中都将遵循HTML5标准来编写代码,该标准进一步赋予了HTML强大的富媒体、富应用以及富内容的能力。

图1-1 HTML所描述的树状数据结构

1.1.2.2 CSS:定义用户界面的外观

CSS是Cascading Style Sheets的英文缩写,在中文里通常被译为“串联样式表”,它本质上是一门定义HTML或XML文档在Web浏览器中所呈现外观的计算机语言。随着HTML可用于定义一般应用程序的用户界面,CSS的应用领域也得到了相应的扩展。我们可以使用这门语言对用户界面中的图片、文本、按钮等元素进行像素级别的精确控制。例如,如果我们想赋予之前的HTML代码一些外观样式,可以在其中添加一个<style>标签,并在标签中添加如下代码。

body {
    color: floralwhite;
    background: black;
}
#content {
    width: 400px;
    height: 300px;
    border-radius: 14px;
    padding: 14px;
    color: black;
    background: floralwhite;
}

接下来,如果我们在Web浏览器中打开保存了这段CSS代码的HTML文档,就会看到如图1-2所示的外观效果。

当然,相信有CSS使用经验的读者一定知道,将上述CSS代码保存为一个单独的.css文件,然后在HTML代码中使用<link>标签来引入它是一个更有利于项目维护的实践方案。本书既然假设读者已经拥有了HTML与CSS的基本使用经验,在这里就不“纠结”于这些细节了。除此之外,同样需要说明的是,本书中所有项目都将遵循CSS3这一最新标准来定义用户界面的外观,该标准新增了圆角效果、渐变效果、图形化边界、文字阴影、透明度设置、多背景图设置、可定制字体、媒体查询、多列布局以及弹性盒模型布局等诸多更为丰富的样式特性,有助于我们构建具有更良好用户体验的应用程序界面。

图1-2 CSS所定义的外观效果

1.1.2.3 JavaScript:定义用户界面的功能

JavaScript是一门专用于操作HTML文档对象的编程语言,它在我们项目中的主要职责就是利用其独有的单线程异步操作模型来响应用户的操作,然后将请求数据发送给服务端,并接收和解析来自服务端的响应数据。总而言之,应用程序界面中的功能性部分基本上是通过JavaScript来实现的。例如,如果我们想在之前的HTML文档中新增一个按钮元素,并且在用户单击该按钮之后,将带有“Hello JavaScript”字样的信息显示在id属性值为content<div>元素中,就可以通过以下代码实现。

<!DOCTYPE html>
<html lang="zh-cn">
    <head>
        <meta charset="UTF-8">
        <title>浏览器端JS代码测试</title>
        <style>
            body {
                color: floralwhite;
                background: black;
            }

            #content {
                width: 400px;
                height: 300px;
                border-radius: 14px;
                padding: 14px;
                color: black;
                background: floralwhite;
            }
        </style>
        <script>
            function sayHello() {
                const div = document.querySelector('#content');
                div.textContent = 'Hello JavaScript';
            }
        </script>
    </head>
    <body>
        <h1>浏览器端的JavaScript</h1>
        <div id="content"></div>
        <input type="button" value="打个招呼!" onclick="sayHello()">
    </body>
</html>

然后,如果我们在Web浏览器中打开保存了这段HTML代码的文档,并单击带有“打个招呼!”字样的按钮,就会看到如图1-3所示的效果。

图1-3 用JavaScript代码定义的功能效果

同样地,相信有JavaScript使用经验的读者也一定知道,将上述文件中的JavaScript代码保存为一个单独的.js文件,然后在HTML代码中使用<script>标签的src属性来引入它是一个更有利于项目维护的实践方案。我们在这里也同样不“纠结”于这些细节。另外,对于本书项目要遵循的标准,我们将以目前主流的ECMAScript6标准(简称ES6)为主。该标准为JavaScript新增了许多过去需要引入jQuery这样的第三方库才能使用的工具,有助于我们构建功能更为强大的应用程序前端。

细心的读者看到这里可能会有一个疑问:为什么到目前为止的演示都是基于Web浏览器来展开的?这是自然的,毕竟我们将要使用的Vue.js框架原本也只是一个单纯的Web前端框架,只是由于uni-app、Electron这一类跨平台框架的出现,将其作用范围扩展到了移动设备以及PC上的一般客户端软件,而这正是我们要在本书中讨论,并将其介绍给读者的项目实践方案。

Vue.js框架原本只是一个单纯的Web前端框架,它通常是基于HTTP来向应用程序的后端发送请求的,所以与之对应的服务端软件自然就应该是HTTP服务。但是,与大家在若干年前用ASP/PHP这类服务端动态页面技术构建的HTTP服务不同的是,如今我们将之前所谓的“动态页面”的构建移到了前端,后端通常已经不再直接参与HTML页面的构建,它现在所要做的就是根据前端发来的HTTP请求进行数据的增、删、改、查,并按照特定的格式返回其所需要的数据。遵照这样的编程思路,我们将推荐使用一种被称为RESTful架构的解决方案。该架构具有结构清晰、方便扩展、易于理解、易于标准化等显著的优势,是目前非常流行的一种互联网软件架构。

下面,让我们简单介绍这种架构:REST是Representational State Transfer(描述性状态迁移)的英文缩写,也有人将其翻译为“表现层状态转化”。其主要设计思想是应用程序的前端使用HTTP的GET、POST、PUT、DELETE请求方法来传递不同的请求状态,并要求其后端根据其请求状态和用URL形式指定的数据资源进行相应的处理,同时返回相应的响应状态和数据资源。具体来说,就是应用程序的前端会通过以下4种HTTP请求方法来表达自己的请求意图。

GET:该请求方法主要用于向服务端请求获取由指定URL所标识的数据。

POST:该请求方法主要用于向服务端请求创建新的数据,有时也用于修改数据。

PUT:该请求方法主要用于向服务端请求修改数据。

DELETE:该请求方法主要用于向服务端请求删除由指定URL所标识的数据。

而使用RESTful架构来构建的应用程序后端则应该具有以下特征。

它会根据前端使用的HTTP请求方法来判断用户要执行的操作意图。

它会根据前端发来的URL来定位用户要处理的数据。

它会以HTTP响应码的形式告知用户操作的结果,并在需要时返回用户所需的数据。

本书中的示例项目在服务端也将全部采用RESTful架构,所以关于如何具体构建基于该架构的应用程序,我们将会在本书的第二、第三部分中详细介绍,在这里读者只需要对这一架构的设计思路有所了解即可。需要特别说明的是,RESTful架构本身只是一种构建应用程序的解决方案,它与我们具体使用的编程语言是无关的,即使用PHP这类传统的服务端编程语言也是可以构建符合RESTful架构的应用程序后端的,只不过需要改变一下设计思路。记住现在后端要响应给前端的内容通常已经不再是由服务端代码在运行时动态构建的HTML页面,而是JSON、XML等格式的数据资源。

为了避免要求读者再多学习一门编程语言,我们打算在本书的项目中也使用基于JavaScript语言的框架来构建应用程序的后端。接下来,本着“工欲善其事,必先利其器”的思想,在进入具体的项目任务之前,我们需要先将项目的编程与调试环境搭建起来。正如我们之前所说,无论是JavaScript的前端框架还是后端框架,它们最初都只能用于构建纯粹的Web应用程序,我们在编程时优先要选择的是JavaScript的基本执行环境。众所周知,JavaScript的基本执行环境主要分为前端的Web浏览器环境和后端的Node.js运行环境两种。下面,我们就分别介绍如何构建这两种环境。

让我们先从最简单的Web浏览器环境开始。目前,很多开发人员会将Google Chrome或Mozilla Firefox浏览器设为自己所在操作系统的默认Web浏览器,它们本身都自带了功能非常齐全的JavaScript执行/调试环境。例如对于Google Chrome浏览器,我们只需到它的官方网站上去下载它,然后安装它,再在其主菜单中依次单击「更多工具」→「开发者工具」,就可以看到如图1-4所示的JavaScript执行/调试环境。

而Mozilla Firefox浏览器则是另一款历史更为悠久的、可扩展的Web浏览器,它在Windows、Linux以及macOS这些主流操作系统上都有相应的版本,读者可根据自己的操作系统到Mozilla Firefox的官方网站上去下载它。安装完成之后,我们在任何网页中按「F12」键或在菜单栏中依次单击「工具」→「Web开发者」→「查看器」,就可以看到如图1-5所示的JavaScript执行/调试环境。

图1-4 Google Chrome浏览器的JavaScript执行/调试环境

图1-5 Mozilla Firefox浏览器的JavaScript执行/调试环境

当然,如果读者打算在Windows 10或macOS中使用它们自带的Web浏览器来充当JavaScript的执行/调试环境,也是可以找到类似的工具的。例如,微软公司用于取代IE的Microsoft Edge浏览器,是基于Chromium开源项目来开发的,其使用方式与Google Chrome浏览器大同小异,只需要在它的主菜单中依次单击「更多工具」→「开发人员工具」,就可以看到如图1-6所示的JavaScript执行/调试环境。

图1-6 Microsoft Edge浏览器的JavaScript执行/调试环境

关于如何在浏览器中使用JavaScript执行/调试环境,我们将会在1.3节中做具体演示,在这里,读者知道如何搭建并启动自己将来需要使用的执行/调试环境即可。另外需要说明的是,本书中的某些项目除了要在浏览器中执行和调试,还需要在各种小程序平台和手机模拟器上进行相似的前端调试工作。

接下来,让我们学习如何构建Node.js运行环境吧!它主要有两种安装方式:通常在Windows和macOS 下,我们会下载.msi和.dmg格式的二进制安装包,然后使用安装包的图形化安装向导来进行安装;而在Linux和UNIX这一类操作系统中,我们则往往会使用APT和YUM这样的包管理器来安装。这两种方式都不复杂,下面我们分别以Windows和Ubuntu为例,简单介绍一下这两种安装方式。

1.2.2.1 使用二进制安装包

在Windows下想要安装Node.js,首先要选择一个合适的版本。在打开Node.js的官方网站之后,我们会看到有LTS和Current两种版本可供下载(见图1-7)。其中,LTS是受到长期支持的版本,其组件通常经历过充分的测试,相对比较可靠、稳定,适合用于正式的项目开发。而Current则是最新的版本,通常包含最新纳入的特性,比较适合想对Node.js本身的特性进行学习和研究的读者。

图1-7 选择版本

下载完.msi格式的安装包之后,我们就可以打开安装包启动它的图形化安装向导。在安装的开始阶段,安装向导会要求我们设置一些选项,大多数时候只需采用默认设置,直接单击「Next」按钮即可。只是在组件选择的页面(见图1-8)中,需要注意,如果你对Node.js的组件并不熟悉,最好选择安装全部组件。另外,请记得单击图1-8中那个「Add to PATH」选项前面的+,这样安装程序就会自动把Node.js和NPM这两个模块的命令路径添加到系统的环境变量里,这对初学者来说是非常方便的。

图1-8 选择安装组件

待一切选项设置完成之后,我们单击下面的「Install」按钮即可完成安装。如果一切顺利,当我们在Windows中打开命令行终端环境,并在其中输入node -v命令,按「Enter」键之后,应该就会看到相关的版本信息,如图1-9所示。

图1-9 在Windows命令行终端中检查版本

1.2.2.2 使用包管理器

在Ubuntu这类Linux/UNIX操作系统中,我们安装软件时往往都会选择使用APT这一类的包管理器。这种安装软件的方式通常简单而方便,只需在Bash Shell这类命令行终端中依次执行以下命令即可。

sudo apt update
sudo apt install nodejs
# 最新的Node.js已经集成了NPM,所以在正常情况下是无须单独安装NPM的
sudo apt install npm

除此之外,我们还能安装n管理器来管理Node.js的版本,其安装命令如下。

sudo npm install -g n

该工具的具体使用方式如下。

sudo n lts            # 长期支持
sudo n stable         # 稳定版
sudo n latest         # 最新版
sudo n 12.4.0         # 直接指定版本
sudo n                # 使用「↑」、「↓」方向键切换已有版本

同样地,如果一切顺利,当我们继续在命令行终端中输入node -v命令并按「Enter」键之后,应该就会看到如图1-10所示的版本信息。

由于我在本书中用来测试项目的Linux服务器上安装的是一个32位的系统环境,而32位的Node.js如今已经不被更新,所以这里看到的是一个早期的LTS版本。在这里,我使用这个测试环境还有一个目的,那就是想证明这类版本上的差异并不会影响本书中所有代码的执行效果。也就是说,即使读者使用的是相对老旧的32位操作系统来学习本书的内容,也完全不必担心这方面的问题。在Node.js运行环境中进行JavaScript代码的执行和调试,我们还需要借助于具体的项目开发工具,下面接着介绍如何配置项目开发所需要的工具。

图1-10 在Bash Shell中检查版本

从纯理论的角度来说,要想编写一个JavaScript应用程序,通常只需要使用Windows操作系统中的“记事本”这一类纯文本编辑器就够了。但在具体的项目实践中,为了在工作过程中获得代码的语法高亮与智能补全等功能以提高编码体验,并能方便地使用各种功能强大的程序调试工具和版本控制工具,我们通常还是会选择使用一款专用的代码编辑器或集成开发环境来完成项目开发。在本书中,我个人推荐读者使用Visual Studio Code编辑器(以下简称 VSCode编辑器)来构建所有的项目。下面,就让我们来简单了解这款编辑器的安装方法,以及如何将其打造成一个可用于开发Vue.js项目的开发环境吧!

1.2.3.1 基于VSCode编辑器的开发环境

VSCode是一款微软公司于2015年推出的现代化代码编辑器,由于它本身就是一个基于Electron框架的开源项目,所以它在Windows、macOS、Linux上均可使用(这也是我选择它作为主编辑器的原因之一)。VSCode编辑器的安装非常简单,在浏览器中打开它的官方下载页面之后,就会看到如图1-11所示的内容。

然后,大家需要根据自己的操作系统来下载相应的安装包。待下载完成之后,我们就可以打开安装包来启动它的图形化安装向导。在安装的开始阶段,安装向导会要求用户设置一些选项,例如选择程序的安装目录、是否添加相应的环境变量(如果读者想从命令行终端中启动VSCode编辑器,就需要激活这个选项)等,一般情况下采用默认设置,直接一直单击「Next」按钮等就可以完成安装。接下来的任务就是要将其打造成可用于开发Vue.js项目的工具。

图1-11 VSCode的下载页面

VSCode编辑器的强大之处在于它有一个非常完善的插件生态系统,我们可以通过安装插件的方式将其打造成面向不同编程语言与开发框架的集成开发环境。在VSCode编辑器中安装插件的方式非常简单,只需要打开该编辑器的主界面,然后在其左侧纵向排列的图标按钮中找到「扩展」按钮并单击它,或直接按快捷键「Ctrl+Shift+X」,就会看到如图1-12所示的插件安装界面。

图1-12 VSCode编辑器的插件安装界面

根据开发Vue.js项目的需要,我在这里推荐读者安装以下插件(但并不局限于这些插件)。

Chinese (Simplified) Language Pack for Visual Studio Code:简体中文语言包,用于将VSCode编辑器的用户界面语言变成中文。

vscode-icons:该插件用于为不同类型的文件加上不同的图标,以方便文件管理。

HTML Snippets:该插件用于在编写HTML代码时执行一些常见代码片段的自动生成功能。

HTML CSS Support:该插件用于在编写样式表时执行自动补全功能。

JavaScript Snippet Pack:该插件用于在编写JavaScript代码时执行自动补全功能。

JavaScript (ES6) Code Snippets:该插件用于在编写符合ES6标准的代码时执行自动补全功能。

ESLint:该插件用于检测JavaScript代码的语法问题与格式问题。

Vetur:该插件可实现针对.vue文件中的代码进行语法错误检查、代码高亮与代码自动补全(配合ESLint插件使用效果更佳)。

npm:该插件可用package.json来校验安装的NPM包,确保安装包的版本正确。

Node.js Modules Intellisense:该插件可用于在JavaScript和TypeScript导入声明时执行自动补全功能。

Node.js Exec:该插件可用Node.js命令执行当前文件或被我们选中的代码。

Node Debug:该插件可实现直接在VSCode编辑器中调试后端的JavaScript代码。

Path Intellisense:该插件用于在编写文件路径时执行自动补全功能。

GitLens:该插件用于查看Git的提交记录。

View In Browser:该插件用于在浏览器中查看静态的HTML文档。

Live Server:该插件可在本地自动构建一个简单的HTTP服务器,是前端开发的一大“利器”。

Debugger for Chrome:该插件可实现直接在VSCode编辑器中调试前端的JavaScript代码,而不必借助浏览器的开发工具。

当然,VSCode编辑器的插件“多如繁星”,读者也可以根据自己的喜好来安装其他功能类似的插件,这些插件满足后面的项目实践需求即可。除此之外,Atom与Submit Text这两款编辑器也与VSCode编辑器有着类似的插件生态系统和使用方式,如果读者喜欢,也可以使用它们来打造属于自己的项目开发工具。

1.2.3.2 WebStorm集成开发环境

如果读者更习惯使用传统的集成开发环境(Integrated Development Environment,IDE),JetBrains 公司旗下的WebStorm无疑是一个不错的选择,它在Windows、macOS、Linux上均可做到所有的功能“开箱即用”,无须进行多余的配置,已经被广大的JavaScript开发者誉为“最智能的JavaScript集成开发环境”。WebStorm的安装方法非常简单,我们在浏览器中打开它的官方下载页面之后,就会看到如图1-13所示的内容。

图1-13 WebStorm的下载页面

同样地,大家在这里需要根据自己的操作系统来下载相应的安装包,待下载完成之后就可以打开安装包来启动它的图形化安装向导了。在安装的开始阶段,安装向导会要求用户设置一些选项,例如选择程序的安装目录、是否添加相应的环境变量和关联的文件类型等,大多数时候只需采用默认设置,直接一直单击「Next」按钮等就可以完成安装。令人遗憾的是,WebStorm并非一款免费的软件。

当然,类似的集成开发环境还有微软公司旗下的Visual Studio Community,它是一款完全免费的集成开发环境软件。如果读者确定自己只在Windows操作系统下进行项目开发,安装Visual Studio Community也是一个很好的选择,至少用它来开发本书中涉及的所有项目应该是够用的。

在配置好JavaScript代码的执行环境与项目开发工具之后,接下来我们要来完成搭建编程环境的最后一步——构建源码管理机制。在本书中,我们会将所有项目的源码存放在一个名为code的目录中(读者可以在计算机中任意自己喜欢的位置创建这一目录,如果你们喜欢也可以赋予该目录别的名字),并使用Git版本控制工具来进行源码管理,操作非常简单,具体步骤如下。

1.先使用Powershell或Bash Shell这类命令行终端打开code目录,并使用git init命令将其初始化为一个本地源码仓库。

2.接下来就可以在code目录下创建项目了,例如,我们可以使用mkdir 00_html_css_js命令为之前的示例创建一个项目目录。

3.然后将我们之前编写的HTML代码保存为一个名为index.htm的文件,并将其存放在00_html_css_js项目目录中。

4.最后我们只需要在code目录中执行以下命令即可完成一次版本提交。

        git add .
        git commit -m "00_html_css_js"

当然,使用Git版本控制工具进行源码管理的操作远不止这些,如果读者对该版本控制工具不熟悉,建议先通过阅读Git的官方文档及其他相关教程来初步了解它的安装方法与基本使用技巧。或者也可以选择使用SVN等其他版本控制工具来进行项目源码的管理,使用这些工具管理源码的方式与我们在这里演示的步骤在本质上是一样的。

至此,我们完成了为本书搭建编程环境的所有工作的介绍,接下来重点讨论代码的具体调试方法。

在讨论具体的调试方法之前,我们首先需要了解“代码调试”究竟是一项怎么样的工作及其背后的基本思路。在计算机领域中,“调试”这个术语在英文中对应的词是“Debug”,从后者想表达的字面信息来看,我们将其翻译成“捉虫子”似乎会更贴切一些。那么计算机领域中的调试工作与“虫子”(bug)究竟有什么关系呢?这就涉及计算机发展史上的一个典故。

计算机历史上的第一个bug

在1947年盛夏的某一天,美国计算机科学家格雷丝·霍珀(Grace Hopper)正在为Harvard Mark II计算机编写程序,突然遇到了机器故障。她花费了很多时间来查找故障的来源,最终在拆开机器之后,发现故障来源竟然是一只被夹扁在两个继电器触点中间的飞蛾。原来,当年的Harvard Mark II是一台依靠控制继电器的开关来执行二进制指令的计算机,发热量巨大,而当时的实验室还未实现全封闭的空调制冷环境,加上天气炎热,机房不得不处于开窗通风的状态,结果导致室内飞蛾乱舞,其中的一只飞进了计算机内部。在这次事件之后,霍珀女士诙谐地将这只虫子的遗体贴在了自己的工作日志中。自此之后,大家就口耳相传地逐渐将计算机故障统称为bug,而排除故障的工作也就随之约定俗成地被称为Debug。

从上述典故中,我们可以了解到旨在排除计算机故障的调试工作往往具有以下特征。

故障产生的源头未必与眼下执行的操作(包括编写的代码)直接相关,它也可能来自我们许久之前的操作(甚至是别人的操作)。

故障经常产生于某些意想不到的细节问题,我们不能“迷信”于自己过去的经验,或者依靠直觉来猜测故障的起因。

所有的计算机故障都是可以得到科学解释的,也许找到这个解释需要花费不少时间,但绝不会出现“灵异事件”。

根据这项工作的以上特征,我个人建议读者在进行代码调试时应该遵循以下基本思路。

坚持根据代码的具体运行环境来进行调试,尽量不要脱离实际运行环境来判断故障产生的原因。

坚持依据代码在运行过程中产生的实际数据来进行调试,可借助但不要迷信于自己过去的经验。

坚持使用严谨细致的科学方法来进行调试,切记不要用某些直觉式的猜测来干扰自己的工作。

在理解了调试工作的本质及其背后的基本思路之后,读者应该大致明白我们在调试代码时要做的事。首先,我们要试验性地让目标代码在各种不同的软硬件环境中运行起来,试验的环境越多越好。然后,如果目标代码在某个环境中“崩溃”了,或者运行结果不符合设计的预期,这时就需要我们采用具体的调试方法介入代码中,跟踪其运行过程并监控其中的数据变化,以便找出导致问题产生的根源所在。最后,根据问题产生的根源设计解决方案。下面,我们介绍几种可用于调试JavaScript代码的常用方法。

当我们只用纯文本编辑器来编写代码时,可选在代码的某些关键位置上使用JavaScript的console对象将要监控的数据输出到控制台,这是最为“简单粗暴”的调试方法。例如在之前的代码中,如果我们想确认sayHello()函数是否得到了正确的调用,并且其变量div是否得到了正确的DOM节点,就可以在代码中添加一个console.log()方法的调用,像以下这样。

function sayHello() {
    const div = document.querySelector('#content');
    console.log('正在调用 sayHello(),此刻变量div的值是:', div);
    div.textContent = 'Hello JavaScript';
}

然后,如果我们在Web浏览器中打开添加上述调试代码的HTML文档,并单击「打个招呼!」按钮,就会在浏览器右侧打开的JavaScript控制台中看到如图1-14所示的输出。

图1-14 用console对象输出调试信息

当然,这种简单粗暴的方法不仅会打乱原有的代码,增加不必要的维护成本,而且它实际上只能用于少量的关键位置。如果大量使用,也会让控制台的输出信息显得杂乱无章,影响我们调试工作的效率和正确性。所以在通常情况下,我们需要借助专用的调试工具来完成较为复杂的调试任务。下面,我们具体介绍这些调试工具的使用方法。

在JavaScript编程过程中,我们常用的调试工具主要有两大类:第一类是之前介绍过的、由 Web 浏览器提供的调试工具,即使是基于uni-app、Electron这一类跨平台框架的客户端软件,它们通常也内置了基于Google Chromium这类开源浏览器的调试工具,在使用方法上是大同小异的;第二类是由VSCode编辑器这种专用开发工具集成的调试器。下面,我们就分别以Google Chrome浏览器和VSCode编辑器为例分别介绍这两类调试工具的使用方法。

1.3.2.1 使用Google Chrome浏览器来调试

如果要想在Google Chrome浏览器中调试之前那段JavaScript代码,我们需要在该浏览器中打开要调试代码所在的HTML文档,并在浏览器的主菜单中依次单击「更多工具」→「开发者工具」,然后在打开的「开发者工具」窗口中选择「Sources」选项卡,就会看到如图1-15所示的界面。

图1-15 「开发者工具」窗口的「Sources」选项卡

如你所见,现在的「开发者工具」窗口被分成了左、中、右3列。接下来,我们需要先在左边这一列中找到要调试的源码文件并单击它,该源码就会随之出现在中间这一列中。然后,我们要通过一种被称为断点的调试机制来设置一些代码执行过程中的观察点,以便观察相关的数据状态。在通常情况下,这些断点的位置就是我们之前要添加console对象调用的地方。例如在这里,我们应该将断点设置在第24行,具体做法就是在「开发者工具」窗口的中间这一列中,单击要设置断点位置的行号之前的空白处,然后刷新当前页面并单击页面中的「打个招呼!」按钮。这样一来,读者就会看到调试工具在我们设置断点的位置暂停代码的执行,并在「开发者工具」窗口的右边这一列中观察到代码运行时的数据,如图1-16所示。

图1-16 「开发者工具」中的断点调试

接下来,我们还可以利用位于「开发者工具」窗口右边这一列顶部的一组调试功能按钮进行更细致的单步调试。如果将鼠标指针在这些按钮上稍做停留,就会看到它们从左到右分别代表以下功能。

Pause/Resume script execution:用于暂停或恢复脚本执行(让代码执行到下一个断点)。

Step over next function call:用于让调试工具跳过下一个函数调用。

Step into next function call:用于让调试工具进入下一个函数调用中。

Step out of current function:用于让调试工具跳出当前执行的函数。

Deactive/Active all breakpoints:用于关闭或开启所有断点(但并不会取消这些断点)。

Pause on exceptions:用于应对异常情况的自动断点设置。

需要说明的是,我们在这里介绍的只是用浏览器调试代码的基本方法,更丰富的调试方法还需要读者自己去探索,这里考虑到篇幅的因素就不展开讨论了。

1.3.2.2 使用VSCode编辑器来调试

如果我们想在编写代码的同时对其进行调试,且又不想频繁地在项目开发工具和浏览器之间来回切换,使用项目开发工具本身提供的调试器无疑是一个更方便的选择。如果想在VSCode编辑器中调试之前的JavaScript代码,我们需要先在VSCode编辑器中打开这段代码所在的HTML文档,并在编辑器界面左侧纵向排列的图标按钮中找到「运行」按钮并单击它,或直接按快捷键「Ctrl + Shift + D」,然后就会看到如图1-17所示的界面。

图1-17 VSCode编辑器的调试界面

然后,在安装了Live Server、Debugger for Chrome这两个插件的情况下,我们只需要单击「创建launch.json文件」,并选择好要调试的项目以及调试环境选项(这里选择的是「Chrome」)。这样一来,VSCode 编辑器就会在当前项目的.vscode目录下创建一个名为launch.json的配置文件。接下来,我们需要将该文件中的默认设置修改如下。

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "chrome",
            "request": "launch",
            "name": "00_html_css_js",
            "url": "http://localhost:5500/00_html_css_js/index.htm",
            "webRoot": "${workspaceFolder}"
        }
    ]
}

如你所见,我们在这里主要做了两项修改:首先是代表当前调试配置的名称name,这主要用于识别当前的调试配置;然后是用于指定被调试目标文件的url。需要注意的是,由于我们在这里是使用Live Server插件来构建HTTP服务的,所以服务端口要改成该服务的默认端口5500

在完成以上配置之后,我们接下来就只需要在源码中设置好断点(设置断点的操作方式与之前介绍的相似),然后在VSCode编辑器中通过单击底部的「Go Live」按钮来启动由Live Server插件自动构建的HTTP服务,并在其主菜单中依次单击「运行」→「启动调试」,或直接按快捷键「F5」就可以启动调试任务了。同样地,当我们在弹出的页面中单击「打个招呼!」按钮时,就会在VSCode编辑器中看到代码的执行停在我们设置的断点处,并在左侧显示出代码运行时的数据,如图1-18所示。

图1-18 VSCode编辑器中的断点调试

在上述调试界面中,源码视图的顶部也存在一组用于进行单步调试的功能按钮,这些按钮的排列顺序与我们之前在浏览器中看到的是完全一致的,读者可以尝试着用它们来进行更细致的调试工作,这里就不再介绍了。另外需要特别说明的是,我们这里演示的只是前端代码的调试,对于后端代码的调试,我们将会在后面具体实现相关项目时做进一步的说明。当然,如果读者希望对VSCode编辑器的调试配置文件及其设置方法能有更全面的了解,也可以去参考韩骏先生所著的《Visual Studio Code权威指南》一书。

在本章中,我们带领读者为接下来要展开的项目实践做了一系列准备工作。首先,我们简单介绍了构建这些项目所需要了解的背景知识,其内容包括项目所遵循的C-S体系结构,以及C-S项目的前、后端所要使用的主要技术。接着,我们介绍了如何搭建接下来将涉及的编程环境,其内容包括如何打开浏览器中的开发工具、如何安装Node.js运行环境、如何安装和配置用于编写代码的编辑器和集成开发环境,以及如何利用版本控制工具构建源码管理机制。最后,我们为读者介绍了代码调试工作的本质、这项工作所应该遵循的基本思路,以及调试工具的基本使用方法。

待读者切实地完成了以上这些准备工作之后,从第2章开始,我们就可以试着来构建各种基于Vue.js框架的项目了。

读者服务:

微信扫码关注【异步社区】微信公众号,回复“e58390”获取本书配套资源以及异步社区15天VIP会员卡,近千本电子书免费畅读。

然我们要以Vue.js框架为核心来展开项目的实践讨论,那么熟悉这个框架本身就是首先要解决的问题。因此在本书的第一部分中,我们将用5章介绍Vue.js框架的基本设计思想与使用方法,这5章内容分别对应一项在使用该框架创建前端应用时需要讨论的议题,具体如下。

第2章 创建前端应用。

第3章 设计用户界面。

第4章 实现Vue对象。

第5章 使用Vue组件。

第6章 使用自动化工具。


在本章中,我们首先会对Vue.js框架做简单的介绍,目的是让读者了解这一框架带来的开发优势,以及本书为什么要选择围绕它来展开关于前端开发的讨论。然后,我们会具体演示如何逐步将第1章中的“Hello JavaScript”示例转换成一个基于Vue.js框架构建的前端项目,目的是借助这一过程让读者了解创建Vue.js项目的基本步骤,以及这些步骤所反映的设计思路。在学习完本章内容之后,希望读者能够:

了解Vue.js框架的设计思想及其所具备的优势;

掌握基于Vue.js框架创建前端项目的基本步骤;

初步理解Vue.js项目的组织方式及其设计模型。

如果粗略地回顾一下最近这七八十年间在“计算机世界”中出现过的各种软件项目,就会发现许多成功的项目都有着一个相似的起源故事,那就是它们最初都只是其创造者为满足自己的需求而将之开发出来的。例如:高德纳·E.克努特(Donald E.Knuth)开发出TeX只是因为他需要给自己写的书排版,莱纳斯·托瓦尔兹(Linus Torvalds)开发出Git只是因为他需要一个能替代BitKeeper的版本控制工具来维护Linux内核项目[1]。Vue.js的故事很凑巧地也大致如此,其作者尤雨溪(Evan You)创建它的时候正在Google的创意实验室(Google Creative Lab)参与关于未来用户交互界面的研究。据尤雨溪本人所说[2],当时的工作需要编写大量的纯JavaScript代码,为了提高工作效率,他认为自己需要一个能专注于构建用户交互界面,同时又简单易用的JavaScript框架,结果一直找不到合适的,于是自己动手开发出了Vue.js。

[1] 2005年,Samba文件服务的开发者安德鲁·崔杰尔(Andrew Tridgell)写了一个链接到BitKeeper存储库的简单程序,不幸被BitKeeper创办人拉里·麦克沃伊(Larry McVoy)认为他要对BitKeeper进行逆向工程,并因此停止了BitKeeper对Linux内核项目的支持。

[2] 这里的信息来自一部名叫Vue.js - The Documentary的纪录片,有兴趣的读者可以在各大视频网站上找到它。

在我个人看来,这些优秀软件项目的起源故事如此“不约而同”是有其内在逻辑的。毕竟从根本上来说,软件本质上只是我们用计算机解决某种具体问题的一套解决方案,所以软件的设计应该是一个由解决某个具体问题的内在需求来驱动的工作。然而学过传统软件工程理论的读者应该都知道,描述需求是一件很难做到完全精确的麻烦事,软件的开发者与其用户之间经常会发生对同一份需求描述的理解不一致的情况,这长期以来都是软件开发过程中会出现的最大难题之一。所以对软件开发者来说,最明确的需求通常是自己的需求。而一旦软件很好地满足了某个明确的需求,就不愁没有类似需求的用户。就Vue.js这个框架来说,从尤雨溪给它起的名字就可以看出作者最初要满足的需求,“Vue”是英文单词“View”在法语中的对应词汇,翻译成中文就是“视图”。在大家所熟悉的传统模型-视图-控制器(Model- View-Controller,MVC)模型[3]中,“View”通常指的是应用程序中用于呈现和操作数据的用户界面,所以Vue.js在设计上优先满足的需求就是构建应用程序的用户界面。很显然,大部分想基于JavaScript语言来构建应用程序的开发者都会面临这个需求。

[3] 在传统的MVC模型中,M是指业务模型,V是指用户界面,C则是指控制器,该模型的设计目的是将M和V的实现代码分离,从而降低它们之间的耦合度,使同一个程序可以使用不同的表现形式。

但是JavaScript社区中的前端框架琳琅满目,我们在本书中为什么偏偏选择用Vue.js来满足构建用户界面的需求呢?其原因和尤雨溪放着Google自家的Angular框架不用,非要自己开发一个新的框架是类似的。与Angular陡峭的学习曲线、包罗万象的功能相比,Vue.js被设计成了一个可以自底向上分层应用的渐进式框架。这意味着,我们可以在构建应用的初期只使用它的核心库来构建视图层,然后根据后续的实际扩展需求来决定是否引入更外层的路由器、状态管理、打包工具等组件。因此选择该框架不仅能让学习曲线显得平缓,还便于我们的代码与其他第三方程序库或既有项目进行整合。另外,我们也可以根据Vue.js官方文档的说明,了解到该框架还具有以下几项更具体的优势。

它使用了虚拟的DOM,这既提高了页面渲染速度,也简化了对HTML页面元素的操作方式。

它采用了与传统HTML类似的模板语法,这相较于JSX这类需要特别学习的模板语法显然更易于上手。

它采用了双向数据绑定的响应式视图模型,其构建的用户界面将由数据来驱动,这有利于提高用户体验。

当然,除了以上纯技术因素,由于Vue.js的作者本人是一个以中文为母语的技术工作者,所以Vue.js社区提供的中文资料也比其他JavaScript前端框架的要更丰富一些,这也是我在本书中选择使用这一框架来讨论项目实践的一个重要原因。另外需要说明的是,我们接下来要讨论的内容更偏向于在构建项目过程中所需要做的步骤,与Vue.js官方文档中提供的教程相比,它们不仅不是简单的重复,甚至还有些内容上的互补,所以我个人会倾向于建议读者搭配Vue.js官方文档来学习本书中所讨论的内容。

和Vue.js官方文档一样,我个人也强烈建议读者在搞清楚一个Vue.js项目的基本组成之前,不要使用Vue CLI这样的自动构建工具来创建项目,因为这样做将不利于培养开发者对项目的完全掌控能力。也正是基于这方面的考虑,我们接下来会选择从零开始,以构建传统的HTML+CSS+JavaScript项目的组织方式来构建本书中的第一个基于Vue.js框架的项目。然后在第5章结束之前,我们会逐步将该项目的组织方式改造成真正的Vue.js项目该有的样子,这样做的目的是让读者能切实地理解Vue.js项目的组织方式,以及这种组织方式背后的设计思想和使用的具体技术。现在闲话少说,让我们正式开始吧!

在第1章的00_html_css_js项目中,我们出于演示方便的考虑,将CSS、JavaScript代码都直接放在了 HTML 文档中。这种代码编写方式的缺点是很明显的:首先,这样做会导致代码之间的耦合度过高,在项目规模扩大之后,不利于样式和脚本代码的重用和后期维护;其次,这样做也会导致Web浏览器和其他客户端每次加载应用程序的用户界面时都只能针对同一个HTML文件发起请求,无法做到只针对用户界面代码中经常发生变化的部分发起请求,对不经常变化的部分(例如样式部分)进行缓存,以减少客户端需要向服务端请求的数据量,提高用户界面的加载速度。接下来,我们既然要将该项目改造成Vue.js项目,顺便就将这一问题也一并纠正了吧!而为了将HTML、CSS、JavaScript代码分开存放,开发者需要在项目中设置一些对应的目录。简言之,我们现在要执行以下步骤来创建本书的第一个项目。

1.先在code目录下创建一个名为01_hello_vuejs的目录,以此作为这个新建项目的根目录。

2.然后在01_hello_vuejs目录下创建一个名为styles的目录,该目录将专用于存放CSS样式文件。

3.继续在01_hello_vuejs目录下创建一个名为scripts的目录,该目录将专用于存放JavaScript脚本文件。

4.使用Powershell或Bash Shell这类命令行终端打开01_hello_vuejs目录,并使用npm init --yes命令来产生默认的配置文件。

5.使用任意文本编辑器打开位于01_hello_vuejs目录下的、名为package. json的配置文件,就可以看到其当前配置如下。

        {
            "name": "01_hello_vuejs",
            "version": "1.0.0",
            "description": "",
            "main": "index.js",
            "scripts": {
               "test": "echo \"Error: no test specified\" && exit 1"
            },
            "keywords": [],
            "author": "",
            "license": "ISC"
        }

我们在这里使用的NPM(Node Package Management)是一款内置在Node.js运行环境中的、主要面向JavaScript语言的包管理器。需要说明的是,NPM包管理器连接着一个全世界最大的JavaScript软件仓库,即npmjs。通过该包管理器,我们不仅可以将自己的项目打包发布到npmjs上,也可以将别人发布到npmjs上的包引入自己的项目中,同时还可以直接用它来安装一些由JavaScript实现的软件工具。当然,对NPM不熟悉的读者也不必担心,我们在后续内容中会结合项目的构建过程逐步为您介绍该包管理器的使用方法。读者在上述JSON文件中看到的实际上是用npm init --yes命令为项目生成的默认选项,下面来具体介绍一下这些选项的作用。

name:用于指定项目被打包发布时要使用的包名,该名称必须由数字、小写字母,以及英文中的“-”和“_”组成,中间不能有空格。

version:用于指定项目被打包发布时需要设定的版本号。NPM包的版本号通常采用X.Y.Z这样的格式来表示(X代表主版本号,Y代表次版本号,Z代表补丁版本号)。

description:用于在项目打包发布时附上说明性文本,以帮助用户了解该项目的基本功能。

main:用于指定项目被打包之后的主入口文件,即用户在引入该程序包时首先要加载的文件,默认值是当前目录下的index.js

scripts:用于设置一些与项目相关的自定义命令,例如在这里,我们只需要用命令行终端打开当前目录并在其中执行npm test命令,就会看到终端输出带有“Error:no test specified”字样的信息。关于这种自定义命令在项目中所能发挥的具体作用,我们将会结合项目的实际需要来为读者一一演示。

keywords:用于在项目打包发布时为其设置关键字,以提高用户在npm的搜索引擎中找到它的概率。

author:用于在项目打包发布时附上作者信息,该信息可以是作者的真实姓名,也可以是他的网名。

license:用于设置项目被打包发布之后使用的许可证书,默认值为ISC,我们也可以将其设置为MIT、BSD等。该选项的设置与版权许可证体系以及开源文化相关,这部分知识不在本书的讨论范围,读者如有兴趣可自行去查阅相关资料。

当然,以上这些只是用npm init命令的--yes参数生成的默认选项。如果读者想在项目初始化时手动配置一些选项,也可以不使用--yes参数。在这种情况下,npm init命令会在命令行终端中以问答的形式要求用户设置项目的一些选项。例如,读者在图2-1中看到的就是用这种方式将00_html_css_js示例初始化成一个项目的过程。

图2-1 使用npm init命令初始化项目

如果从实际操作的角度来考虑,我个人更倾向于选择先用默认选项的方式生成package. json文件,然后通过直接编辑该文件来配置项目。因为在现实的生产环境中,我们将项目打包发布时要配置的选项通常远不止上面这些,届时添加其他选项的工作通常也只能用编辑package.json文件的方式来完成。当然,基于技术学习规律方面的考虑,关于其他可配置的选项及其相关的作用,我们将等到在项目中实际用到它们时再一一为读者介绍。而现在,我们是时候为自己的项目加载Vue.js框架了。

既然要基于Vue.js框架来构建项目,那么“如何在项目中正确地加载框架”就成了我们接下来首先要解决的问题。在这里,“正确”这个词包含着两层含义:首先,由于Vue.js框架是一个非常活跃的开源项目,它的版本一直在持续不断地更新,所以开发者应该要能根据项目的实际需要来为要加载的框架选择一个合适的发行版,这也是实现“正确地加载框架”的一个重要因素;其次,Vue.js框架以何种方式被加载到项目中也会在很大程度上影响后续的开发与维护工作。因此,让我们先来解决这个问题吧!

2.2.2.1 选择适用版本

在我开始本书的写作之前的一个月,Vue.js框架发布了它的3.0版本。这一版本及其后续版本(以下简称3.x版本)的Vue.js框架在使用方式上发生了较大幅度的变动,近几个月来在JavaScript社区引起了热烈的讨论,有人欢迎新版本带来的改变,有人则持有怀疑态度,整体看来要想在社区中达成共识还需要一些时日。当然,框架的新版本是否能获得成功可以留待时间来检验,但眼下要决定的是我们在本书里采用该框架的哪一个发行版。对于这个问题,我做出了如下两点思考。

本书要讨论的是项目实践方面的问题。在大部分项目实践中,选择使用最新版本的工具算得上是一种非常激进的策略。因为这样做会给项目带来很大的不确定性,这通常不是一个负责任的做法。况且,Vue.js 3.x大幅度地改变了该框架的使用方法,这意味着之前已有的Vue.js 2.x代码与它之间会存在或多或少的兼容问题。在实际项目环境中,无法高效地重用现有代码也会在很大程度上影响项目的开发效率。所以,我个人更倾向于建议读者在项目实践中采用“够用就好”的保守策略,至于新版本,还是“让子弹先飞一下”吧!

也正是由于Vue.js 3.x在框架的使用方式上做了很大幅度的改变,一个月左右的时间也不足以让我完全深入地理解这些变化背后的设计意图,更谈不上分享有关项目实践方面的经验。所以从写作的角度来考虑,直接在本书中使用Vue.js 3.x也实在不是一个负责任的选择。

所以经过再三考虑,我决定仍将使用Vue.js框架的2.x版本来完成本书中所有项目的实践演示。当然,考虑到部分读者的需要,我们会在适当的地方讨论一下Vue.js 3.x带来的变化。

2.2.2.2 框架加载方式

在确定要使用哪一个版本的Vue.js框架之后,接下来的工作就是将框架加载到项目中。和大多数基于JavaScript语言开发的前端程序库和应用框架一样,在项目中加载Vue.js框架也主要有CDN服务和本地文件这两种方式。下面就让我们分别介绍这两种加载方式以及它们各自的优势。

2.2.2.3 CDN服务

CDN是Content Delivery Network的英文缩写,在中文中通常被翻译为“内容分发网络”。顾名思义,这是一种利用现有网络系统中最靠近目标用户的服务器节点,以实现更快、更可靠地分发音乐、图片、视频、应用程序以及其他数据资料的服务方式,目的是提供高性能、可扩展及低成本的网络资源给用户。换言之,当我们使用CDN服务的方式来加载Vue.js框架时,框架的源码文件应该被存储在CDN服务网络中,然后该服务网络会集中负责处理针对该框架源码的访问请求并维护该框架的源码,而我们只需要在相关的HTML文档中使用<script>标签来引用该CDN服务的URL即可,像以下这样。

<!-- 加载开发环境版本,该版本包含有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 或者 -->
<!-- 加载生产环境版本,该版本优化了文件大小和载入速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

在上述代码中,我演示了如何使用cdn.jsdelivr.net提供的CDN服务来加载Vue.js框架,这也是Vue.js官方文档中推荐的服务。至于是该采用开发环境的版本,还是生产环境的版本,这就要取决于具体的使用场景了。在通常情况下,我个人建议读者在程序开发阶段先采用反馈信息相对丰富的开发环境版本,等到程序发布之时再切换至更追求执行效率的生产环境版本。下面,我们来了解使用CDN服务的优势。

CDN服务网络的总承载量通常要比单一骨干型网络大得多。这使得它可以承载的用户数量比起传统单一服务器要多上许多。

CDN服务网络本质上是一种分布式网络,它的服务器会被布置到各种不同的地方,这有助于减少计算机之间互连的流量,进而降低带宽成本。

CDN服务通常会指派离目标位置较近、网络也较顺畅的服务节点将资料传输给用户,这或多或少有助于提高该服务响应请求的速度。

CDN服务网络中存储的资源通常有异地备份,当某个服务节点发生故障时,系统将会调用其他邻近服务节点上的资源,以提高其可靠性。

CDN服务会提供给资源提供者更多的控制权,即提供资源服务的人可以针对客户、地区,或是其他因素来做相应的调整。

当然,这种加载框架的方式归根结底还得依赖于现实中的具体网络环境,甚至很多时候我们还需要依赖国外的网络环境。我个人建议读者将框架文件下载到本地来加载。

2.2.2.4 本地文件

正如上面所说,最好的选择是将Vue.js的框架文件下载到本地,然后以本地文件的方式来加载它们。下载Vue.js框架的方式有很多,但为了便于更新版本,人们通常会选择使用NPM这类包管理器来下载JavaScript的各种第三方库和应用框架。具体做法就是在之前创建的01_hello_vuejs目录下执行npm install vue --save命令。在这里,npm install vue命令的作用是将被发布到npmjs软件仓库中的Vue.js框架安装到本地,而--save参数的作用则是指定将框架安装到当前项目中。如果安装过程一切顺利,我们就会看到当前项目的根目录下多了一个名为node_modules的目录,NPM安装到项目中的第三方库或应用框架都将被存放在该目录下。除此之外,读者还会发现之前生成的package.json文件被修改了,它现在的内容如下。

{
    "name": "01_hello_vuejs",
    "version": "1.0.0",
     "description": "",
    "main": "index.js",
    "scripts": {
       "test": "echo \"Error: no test specified\" && exit 1"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "dependencies": {
        "vue": "^2.6.12"
    }
}

如你所见,现在的项目配置中多了一个名为“dependencies”的选项。该选项的作用是声明当前项目所依赖的第三方库或应用框架,以及它们的版本要求。例如在这里,我们的项目依赖的是Vue.js框架,并且其版本应在2.6.12以上(请注意,这里的“^”代表的是“以上”的概念,即不能低于指定的版本)。接下来,我们就只需要在HTML文档的<script>标签中指定Vue.js框架文件所在的相对路径即可,像以下这样。

<!-- 加载开发环境版本,该版本包含有帮助的命令行警告 -->
<script src="node_modules/vue/dist/vue.js"></script>
<!-- 或者 -->
<!-- 加载生产环境版本,该版本优化了文件大小和载入速度 -->
<script src="node_modules/vue/dist/vue.min.js"></script>

同样地,我们在这里也可以根据项目所处的阶段来决定是采用开发环境版本还是生产环境版本。这样一来,我们就解决了框架文件的存储方式问题。但有过JavaScript使用经验的读者应该知道,在HTML文档中直接使用<script>标签来加载Vue.js框架依然不是最理想的方式,因为这样做会导致该框架中定义的所有对象名称都被暴露在全局域中,有可能会带来一些无法预测的命名冲突问题。所以更为理想的做法应该是,先利用<script>标签中新增的模块类型属性(即type="module")来外链一个自定义的JavaScript代码文件,像以下这样。

<script type="module" src="main.js"></script>

然后在该代码文件中使用ES6新增的模块机制来加载Vue.js框架。但需要特别注意的是,Vue.js框架在默认情况下并不支持ES6的模块机制,因此在使用import语句加载该框架时,我们必须要特别指定支持在浏览器端使用ES6模块机制的那个构建版本[4],像以下这样。

[4] 关于Vue.js的这些需要特别指定的构建版本,读者如有兴趣可自行查阅Vue.js 2.x官方文档中的框架安装部分。

// 加载开发环境版本,该版本包含有帮助的命令行警告
import Vue from './node_modules/vue/dist/vue.esm.browser.js';
// 或者
// 加载生产环境版本,该版本优化了文件大小和载入速度
import Vue from './node_modules/vue/dist/vue.esm.browser.min.js';

当然,这样做也就意味着接下来要编写的代码只能在支持ES6的浏览器中运行,但读者也不必过于担心这方面的问题,我们可以使用一种更具普适性的框架加载方式,眼下只是为了后面能更深入地探讨Vue.js项目的组织方式,暂时先使用HTML+JavaScript这种较为传统的方式来组织当前这个项目。

在了解了如何正确地将Vue.js框架加载到项目中之后,接下来就可以正式在项目中创建源码文件了。我们在本章的任务是将第1章中的“Hello JavaScript”示例转换成一个功能相同,但使用Vue.js框架构建的前端项目,其具体步骤如下。

1.将code/00_html_css_js目录下的index.htm文件复制到code/01_hello_ vuejs目录中。

2.在code/01_hello_vuejs/styles目录下创建一个名为main.css的文件,并将index.htm文件中位于<style>标签之间的样式代码复制到该文件中,具体如下。

        body {
           background: black;
           color: floralwhite;
        }

        #content {
           width: 400px;
           height: 300px;
           border-radius: 14px;
           padding: 14px;
           color: black;
           background: floralwhite;
        }

3.在code/01_hello_vuejs/scripts目录下创建一个名为main.js的文件,并在其中编写如下代码。

        // 加载开发环境版本,该版本包含有帮助的命令行警告
        import Vue from '../node_modules/vue/dist/vue.esm.browser.js';
        // 或者
        // 加载生产环境版本,该版本优化了文件大小和载入速度
        // import Vue from '../node_modules/vue/dist/vue.esm.browser.min.js';
        const app = new Vue({
           el: '#app',
           data: {
              app_title: 'Vue.js 前端应用示例',
              message: ''
           },
           methods: {
              sayHello: function() {
                 this.message = 'Hello,Vue.js app.';
              }
           }
        });

4.将code/01_hello_vuejs目录下的index.htm文件中的代码修改如下。

        <!DOCTYPE html>
        <html lang="zh-cn">
           <head>
              <meta charset="UTF-8">
              <title>浏览器端JS代码测试</title>
              <link rel="stylesheet" type="text/css" href="styles/main.css" />
              <script type="module" src="./scripts/main.js"></script>
           </head>
           <body>
              <div id="app">
                 <h1> {{ app_title }} </h1>
                 <div id="content"> {{ message }} </div>
                 <input type="button" value="打个招呼!" v-on:click="sayHello()">
              </div>
           </body>
        </html>

接下来,如果我们在Web浏览器中打开上面的index.htm文件,就会看到如图2-2所示的效果。

图2-2 Vue.js版本的“跟大家说Hello”

另外需要补充说明的是,如果在调试Vue.js前端应用时觉得浏览器自带的开发者工具还有些不尽如人意,也可以按照Vue.js官方文档的指示,为浏览器安装一个名叫Vue Devtools的插件。该插件是一个专用于调试Vue.js前端应用的工具,在目前的主流Web浏览器中都有相应的版本。我们在Google Chrome浏览器中安装了该插件之后,用它打开上述index.htm文件时看到的界面,如图2-3所示。

图2-3 Vue Devtools的界面

关于该工具的具体使用方法,我们会在后续的项目实践中,根据实际需要来为读者一一演示。下面,让我们先通过上面这个示例来简单认识一下Vue.js前端应用的组织方式与设计思路。

从上述示例中,读者应该可以看出Vue.js前端应用的基本组织方式。首先,项目中至少会有一个用于描述用户界面布局的HTML模板文件。在该模板文件中,我们除了会设置传统的HTML标签,通常还会使用一系列由Vue.js框架定义的模板指令来控制用户界面的显示内容。例如在上述index.htm文件中,我们在<input type="button">标签中就使用了v-on:click指令,这就是Vue.js框架定义的、用于注册事件处理函数的指令。关于Vue.js框架定义的这些指令的具体使用方法,我们将会在第3章中为读者详细介绍。

接下来,我们会在与该HTML模板文件相关联的JavaScript代码中加载Vue.js框架,并创建一个Vue类型的对象。该对象的基本组成成员有以下3项。

el成员:该成员的值可以是任何一个符合CSS选择器语法的字符串,例如#ID、CLASSNAME等。它主要用于设置当前Vue对象所绑定的容器标签,通常情况下会是一个<div>标签,当然也可以是HTML5中新增的<header><footer>等标签,Vue.js框架定义的所有模板指令都必须在该标签内使用才能发挥其功能。例如在本章的示例中,Vue对象绑定的是id属性值为app<div>标签。

data成员:该成员用于设置模板文件中绑定的数据,它的值本身也是一个JSON格式的对象,该对象的每个成员都对应一个模板文件中绑定的对象。例如在本章的示例中,我们在data成员中分别定义了app_titlemessage这两项在模板文件中被绑定的字符串数据。

methods成员:该成员用于设置模板文件中注册的事件处理函数,它的值也是一个JSON格式的对象。该对象的每个成员都对应一个已在模板文件中用v-on指令注册的事件处理函数。例如在本章的示例中,我们在methods成员中定义的sayHello()函数就是模板文件中用v-on指令注册的click事件处理函数。

当然,以上这些只是Vue对象应该有的基本成员,在后面的章节中,我们将会根据项目开发的实际需要陆续为读者介绍如何为该对象添加其他成员,以及这些成员各自的功能。总而言之,在Vue.js前端应用的这种组织方式中,JavaScript代码与HTML标签的交互方式并不像使用原生应用程序接口(Application Program Interface,API)那么直接,它通过先在HTML标签中嵌入一系列由Vue.js框架定义的模板指令来绑定数据,然后通过在JavaScript代码中修改这些被绑定的数据来修改HTML标签的显示方式与内容。我们通常将这种用数据内容的变化来驱动整个程序业务运作的编程模型称为MVVM

MVVM是Model-View-ViewModel的英文缩写,它本质上是传统的MVC模型在前端开发领域中的一种变化。MVVM与MVC模型的唯一的区别就是,它将应用程序中业务逻辑这部分的实现方式由原先需要与 View 和 Model 进行三方单向循环交互的Controller实现改变成了可分别与View和Model进行双向交互的ViewModel实现。其主要设计目的是将应用程序中代表用户界面部分的 View 实现进一步抽象化,使其彻底与代表数据处理部分的Model实现分离开来。总体而言,MVVM可以为我们的前端项目带来以下几大优势。

降低耦合度:在MVVM中,View部分的实现可以独立于Model部分的实现来进行修改,甚至是重构。

提高重用性:在MVVM中,同一个ViewModel 实现可以绑定到多个不同的View实现上。这意味着,我们可以为同一个业务逻辑实现设计各种不同的用户界面。

有利于分工:在MVVM中,我们可以让开发人员专注于业务逻辑的开发,而将用户界面的设计交给更专业的设计人员,以充分发挥分工协作的优势。

有利于测试:众所周知,直接对应用程序的用户界面进行自动化测试历来是比较困难的,但到了MVVM中,类似这样的测试可以围绕着ViewModel的实现来展开。这可极大地降低我们编写自动化测试代码的难度。

如果读者想使用Vue.js 3.x来编写本章的项目,可以根据该框架的官方文档中提供的安装教程对之前的操作做出一些改变。首先,使用NPM在项目中安装框架时,命令应该改为npm install vue@next --save。然后,将项目的main.js文件中的代码修改如下。

// 加载开发环境版本,该版本包含有帮助的命令行警告
import { createApp } from '../node_modules/vue/dist/vue.esm-browser.js';
// 或者
// 加载生产环境版本,该版本优化了文件大小和载入速度
// import { createApp }
//     from '../node_modules/vue/dist/vue.esm-browser.prod.js';

const app =  {
   data: function() {
      return {
         app_title: 'Vue.js 前端应用示例',
         message: ''
      };
   },
   methods: {
      sayHello: function() {
         this.message = 'Hello,Vue.js app.';
      }
   }
};
createApp(app).mount('#app');

从上述代码中可以观察到,在切换至Vue.js 3.x框架时,除了要加载的框架文件在名称上有所变化,以及app对象的data成员变成了一个函数对象外,更重要的是,加载app对象的方法也发生了些许变化。现在我们需要先调用一个名叫createApp()的函数来挂载app对象,然后在其返回值上调用一个名叫mount()的函数来关联与该对象关联的容器标签。

在本章中,我们首先对Vue.js框架做了简单的介绍,向读者详细解释了本书为什么要选择围绕Vue.js框架来展开项目的开发实践。然后,我们从构建项目目录开始,为读者具体演示了如何使用NPM初始化项目并安装框架、如何在项目中正确地加载框架,如何逐步将第1章中的“Hello JavaScript”示例转换成一个使用Vue.js 2.x/3.x框架构建的前端项目。我们通过这些演示过程为读者介绍了Vue.js前端应用的基本组织方式,以及这种组织方式所遵循的MVVM。

读者服务:

微信扫码关注【异步社区】微信公众号,回复“e58390”获取本书配套资源以及异步社区15天VIP会员卡,近千本电子书免费畅读。


相关图书

TypeScript全栈开发
TypeScript全栈开发
Java EE企业级应用开发实战(Spring Boot+Vue+Element)
Java EE企业级应用开发实战(Spring Boot+Vue+Element)
Flutter内核源码剖析
Flutter内核源码剖析
智能前端技术与实践
智能前端技术与实践
从0到1:ES6快速上手
从0到1:ES6快速上手
Angular开发入门与实战
Angular开发入门与实战

相关文章

相关课程