



Web开发不断面向工程化发展,诞生出了很多开发框架。行业中使用较多的以Vue、React和Angular为主,更早的还有jQuery、Bootstrap等。建立开发框架的目的,是为了解决Web开发中遇到的一些问题和挑战,解决开发中遇到的一些重复的、复杂不易解决的实际问题,提高开发效率,使开发变得更加高效、可维护和规范化。每个框架都拥有自己一套完整的生态系统,具备解决某些特定问题的能力,并配套相关的构建、打包工具等,从而使Web开发逐渐变得简单化。
需要说明的是,开发框架都是使用JavaScript代码实现的,学习Web框架必须具备一定的JavaScript基础。
Vue是一套用于构建用户界面的渐进式的JavaScript框架,它基于标准的HTML、CSS和JavaScript构建,并提供了一套声明式、组件化的编程模型,帮助用户高效地开发用户界面。无论是简单的还是复杂的界面,Vue都可以胜任。Vue有两个核心功能:声明式渲染和响应性。
(1)声明式渲染:Vue基于标准的HTML拓展了一套模板语法,使得我们可以声明式地描述最终输出的HTML和JavaScript状态之间的关系。
(2)响应性:Vue会自动追踪JavaScript状态,并在其发生变化时响应式地更新DOM。
Vue是一个框架,也是一个生态。Vue的功能覆盖了大部分前端开发常见的需求,但Web世界是十分多样化的,不同的开发者在Web上构建的东西可能在形式和规模上会有很大的不同。考虑到这一点,Vue的设计非常注重灵活性和“可以被逐步集成”这个特点。根据需求情况不同,可以用不同的方法使用Vue。
(1)无须构建步骤,渐进式增强静态的HTML。
(2)在任何页面中作为Web Components嵌入。
(3)单页应用(SPA)、服务端渲染(SSR)。
(4)Jamstack/静态站点生成(SSG)。
(5)开发PC端、移动端、WebGL,甚至是命令行终端中的界面。
我们称Vue为渐进式框架的原因是,对于初学者而言,只需要具备基础的HTML和JavaScript知识,就可以使用Vue。而一个有经验的开发者,可以从以上多种方式中选择最佳方式来使用Vue。但不论选择哪种方式,Vue都可以保持相同的开发效率。在不断继承的过程中,它与用户共同成长,适应用户的不同需求,所以又称为“渐进式”框架。
Vue的一个标志性功能是单文件(也被称为*.vue文件,英文Single-File Components,缩写为SFC),单文件组件会将一个组件的逻辑(JavaScript)、模板(HTML)和样式(CSS)封装在同一个文件里,以“模板+JavaScript+CSS”的形式呈现。在Vue项目中,如果您的用例需要进行构建,我们推荐用单文件来编写Vue组件。一个单文件组件示例如代码1-5所示。
代码1-5 Vue单文件组件
Vue是一个轻量级的框架,核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目进行整合。但是,使用Vue框架必须要掌握一些基础知识,如通过多种方式创建一个Vue项目(命令行方式、CDN等)、模板语法、响应式双向数据绑定、事件处理、Vue生命周期等。
在Vue项目应用规模化后,需要清楚Vue单文件SFC的工作模式、Vue的构建工具、路由管理、状态管理,以及了解Vue生命周期等。
(1)Vue SFC。它是Vue框架指定的文件格式,必须交由@vue/compiler-sfc编译为标准的JavaScript和CSS才能够工作。编译后的SFC是一个标准的JavaScript(ES)模块,所以,使用SFC必须使用构建工具。在构建配置正确的前提下,用户可以像导入其他ES模块一样导入SFC。
(2)脚手架。Vue CLI是基于Webpack的Vue工具链,通常在Vue2.x项目中使用,现处于维护模式。Vue3.x中推荐使用Vite,除非用户依赖特定的Webpack的特性,现阶段还是建议使用Vite开始新的项目。
(3)路由管理。Vue很适合用来构建单页应用,在这类单页应用中,推荐使用官方支持的路由库——Vue Router。它与Vue.js核心深度集成,让用Vue.js构建单页应用变得轻而易举。Vue Router的功能包括嵌套路由映射、动态路由选择、模块化、基于组件的路由配置、路由参数、查询、通配符、展示由Vue.js的过渡系统提供的过渡效果、细致的导航控制、自动激活CSS类的链接、HTML 5的history模式或hash模式、可定制的滚动行为、URL的正确编码等。路由管理是Vue项目开发中的重要内容。
(4)状态管理。理论上,每一个Vue组件实例都在“管理”它自己的响应式状态。每一个Vue组件都由状态、视图、交互三部分组成,每一项都是一个独立的单元。对于一个“单向数据流”,这三部分的驱动过程很好理解。但当有多个组件共享一个共同的状态时,多个视图可能都依赖于同一份状态,或者来自不同视图的交互可能需要更改同一份状态。这种情况可以使用响应式API进行简单的状态管理,但对于大型项目而言又显然不够。Vue官方开发了Vuex、Pinia状态管理库,可用于解决上述问题。其中,Pinia在Vue 2和Vue 3中都可以使用,Vuex适用于在Vue 2中使用,现在处于维护模式,新项目建议选择Pinia。
(5)生命周期。每个Vue组件实例在创建时都需要经历一系列的初始化步骤,例如设置数据侦听、编译模板、挂载实例到DOM以及在数据改变时更新DOM等,每一个过程的执行都需要运行被称为“生命周期钩子”的函数,让开发者有机会在特定阶段运行自己的代码。例如,mounted钩子在组件完成初始渲染并创建DOM节点后运行,在这个钩子中,我们可以执行给DOM节点赋值等操作。还有一些其他钩子,会在实例生命周期的不同阶段被调用,可以查看官方API了解每个钩子的具体内容。
上述内容我们反复提到Vue 3.x和Vue 2.x,Vue 2.x是最初通行的Vue版本,Vue 3.x是当前最新的版本。它们还在不断发展,后面可能还会有新的版本更新,可以参考Vue官方API进行了解和学习。
React是由Facebook打造而成的一套JavaScript Web库,主要用于构建高性能及响应式的用户界面。React负责解决其他JavaScript框架所面对的一大常见难题——对大规模数据集的处理。React使用虚拟DOM,并在发生变更时利用补丁安装机制对DOM中的dirty部分进行重新渲染,是一种函数式的编程理念。当您刚开始一个React应用时,可以通过HTML的script标签引入,这样可以立即启动并使用React。但随着应用的规模越来越大,可能需要更加集成化的方式安装,这时可以使用集成的工具链,它们只需很少甚至零配置,就能充分利用丰富的React生态。React推荐的工具链如下。
(1)Create React App:适用于学习React或创建一个新的单页应用。
(2)Next.js:适用于使用Node.js构建服务端渲染的网站。
(3)Gatsby:适用于构建面向内容的静态网站。
(4)Neutrino:把Webpack的强大功能和简单预设结合在一起,包括React应用和React组件的预设。
(5)Parcel:一个快速、零配置的网页应用打包器,且可以搭配React一起工作。
(6)Razzle:一个无须配置的服务端渲染框架,它提供了比Next.js更多的灵活性。
使用React工具链可以完成的任务:扩展文件和组件规模、使用来自npm的第三方库、尽早发现常见错误、在开发中实时编辑CSS和JS、优化生产输出等。
React是一个JavaScript库,学习React,同样需要对JavaScript语言有基本的了解。
React框架的特点如下。
(1)不直接对DOM进行操作,引入一个“虚拟DOM”的概念,安插在JavaScript逻辑和实际的DOM之间,使用性能较好。
(2)虚拟DOM解决了跨浏览器问题,提供标准化的API,甚至在IE 8中使用都是没有问题的。
(3)代码更加模块化,重用代码更容易,可维护性高。
(4)Flux是一个用于在JavaScript应用中创建单向数据层的架构,它随着React视图库的开发而被Facebook概念化,遵循单向的数据驱动流程。
(5)兼容性好。
1)JSX
JSX是一个JavaScript的语法扩展,React提供了使用了JSX来代替实现的方法,它不强制使用。但在开发时还是建议配合JSX使用,因为它可以很好地描述UI应该呈现出的应有交互的本质形式。JSX从形式上来看,可能和模板语言有点相似,但它具有JavaScript的全部功能,JSX表达式、JSX对象等在学习React时都需要掌握。
2)组件和Props
组件允许用户将UI拆分为独立可复用的代码片段,与Vue框架的组件概念类似。组件类似于JavaScript函数,它可以接受任意的入参(即props),并返回用于描述页面展示内容的React元素。在React中,组件的类型有函数组件、class组件、渲染组件和组合组件,其中JavaScript函数是最简单的定义组件的方式,其次是ES6的class组件,渲染组件和组合组件在使用中的场景最多。React应用程序是由组件组成的,组件可以小到一个按钮,也可以大到整个页面。组件在开发中随时都会用到,是必须要掌握的一项内容。
3)生命周期
在具有许多组件的应用程序中,当组件被销毁时释放所占用的资源是非常重要的。例如,当一个组件第一次被渲染到DOM中时,为其设置一个计时器,“第一次被渲染到DOM中”在React中被称为“挂载(mount)”。而当DOM中的该组件被删除时清除计时器,“组件从DOM中删除”在React中被称为组件“卸载(unmount)”。我们可以为组件声明一些特殊的方法,当组件挂载或卸载时就会去执行这些方法,这些方法叫做“生命周期方法”。
除上述基础知识外,在实际应用中还需要学习更多的高阶知识,如代码分割、高阶组件、性能优化等,这些决定了我们能否提高工作效率、开发出更多更好用的功能。
Angular也是一个基于TypeScript构建的开发平台,包括一个基于组件的框架,用于构建可伸缩的Web应用;一组完美集成的库,涵盖各种功能,包括路由、表单管理、客户端-服务器通信等;一套开发工具,可帮助用户开发、构建、测试和更新代码。
(1)模板功能强大丰富,并且是声明式的,自带丰富的Angular指令。
(2)是一个比较完善的前端MVC框架,包含模板、数据双向绑定、路由、模块化、服务、过滤器、依赖注入等所有功能。
(3)自定义Directive(指令),比jQuery插件还灵活,但是需要深入了解Directive的一些特性。简单的封装容易,复杂一点的话官方没有提供详细的介绍文档,可以通过阅读源代码来找到某些我们需要的东西,如在directive使用$parse。
(4)ng模块化。比较大胆地引入了Java的一些内容(依赖注入),能够很容易地写出可复用的代码,对于敏捷开发的团队来说非常有帮助。
学习Angular需要掌握的主要知识要点如下。
1)组件
组件是Angular应用的关键构造块。每个组件包括一个HTML模板——用于声明页面要渲染的内容、一个用于定义行为的TypeScript类、一个CSS选择器——用于定义组件在模板中的使用方式、要应用在模板上的CSS样式(可选)。
用户可以手动创建一个组件,也可以使用Angular CLI创建一个组件。其中,Angular CLI是用来创建组件最简单的途径。
2)模板
每个组件都有一个HTML模板,用于声明该组件的渲染方式。用户可以以内联的方式或用文件路径来定义此模板,Angular使用额外的语法扩展了HTML,使用户可以从组件中插入动态值。当组件的状态更改时,Angular会自动更新已渲染的DOM——此功能的应用之一是插入动态文本。
3)依赖注入
依赖注入让用户可以声明TypeScript类的依赖项,而无须关心如何实例化依赖项。这种设计模式能让用户写出更加可测试,也更灵活的代码。尽管了解依赖注入对于开始用Angular并不是至关重要的事,但我们还是强烈建议用户将其作为最佳实践,并且Angular自身的方方面面都在一定程度上利用了它。
另外,Angular最显著的特征是其整合性,它是由单一项目组常年开发维护的一体化框架,涵盖M、V、C/VM等层面,不需要组合、评估其他技术就能完成大部分前端开发任务。这样可以有效降低决策成本,提高决策速度,对需要快速起步的团队是非常有帮助的。
上述三种框架各有优劣,开发者可根据项目需要或个人爱好进行选择。本书中的所有示例都是基于Vue框架开发,其中一些简单的小型demo也会使用一个静态页面(如1.1.3节中的示例)。用户可以参照这种模式,如果是开发一些小型的、功能不复杂的demo,可以使用一个静态页面来用作演示或测试使用。如果是功能比较复杂或者需要部署的系统,推荐以工程化方式来实现。搭建一个完整Vue工程的示例,在本书第12章中有详细介绍。