Press "Enter" to skip to content

单页应用程序(SPA)形式理论及React应用一般结构

作为「前端开发者」或「Web应用设计师」,对 单页应用程序(SPA)的形式[注]和逻辑结构[注]有特别细致的了解 是他的专业基础。这些基础知识,有助于作为「开发者」精确的 对(设计方案上的)某种功能设计 进行技术实现,也有助于作为「设计师」更专业的将用户需求转化具体的容易技术实现的设计方案。

注:根据被认识的主体不同(矿物和生物),形式有静态属性,和动态规律,两种;程序是种被动弱智生命;

注:逻辑结构就是质料结构(构造)

「设计案」是设计师和开发者沟通的中间媒体,「设计案」全称构造设计案,Web应用程序(WGP)的构造设计案是对项目需求文档的技术具体,是对程序源码的逻辑概述。WGP构造设计案异常的重要,其制作(由设计师)和使用(由开发者)都是以WGP理论为基础的,是它的一种应用。

然,这里有个疑问,形式理论如何为「设计案」的基础呢?原因为,「某物理论」可指导认识和制造「某物」,以及「某物」的逻辑模型,逻辑模型就是设计案,算是某物成型的半成品。 「某物理论」可指导可举一个简单的例子,例如,GP界面程序的MVC结构模式,构件关系和构件逻辑都是基于GP理论的。

单页应用程序 发展有一段时间,然而纯粹的完整的 SPA理论[注],我还没有读到过。本文参考《Master React 2016》的部分与SPA理论相关的内容,我以为还不错,在其基础上丰富一下。

注: SPA是Web 应用程序的一种,我们更关心的是通用的WGP理论,是以WGP为对象的理论,WGP分SPA(单页)和 MPA(多页)。当然,本文可能只关心SPA(前端)理论,然它可用作启发抽象出通用的WGP理论。

什么是单页应用程序

单页应用程序 (SPA) 是富应用( rich application)的一种,它功能的“丰富”程度好比普通的桌面应用程序,复杂会话界面,优质体验,即时响应,智能高级等,然而SPA是运行在浏览器上的,以网页的形式,这正如它的名字显示的特点。与传统多页(MPA)网站不同,在 SPA 中,只有一个主页面加载到浏览器中,这个初始页面加载后,其他资源(如脚本、样式表、数据和程序资源,如图像)将异步加载,初始页面不会重载。

EM:这里将SPA和桌面应用,和MPA作对形式差对比;

EM:“页面”和后面“URL”是SPA的Web的特征,页面对应是交互界面(桌面应用也有交互界面);

前端Router与后端Router

初始页面不会重载的特征是,在整个应用程序的生命周期中,页面URL中“井”号标记 (#) 前面的内容[注] 通常不会更改。也就是说,浏览器不会向服务器请求任何后续的”页面”。

注:为了方便表述,接下来,有关URL中“井”号前内容的 还叫「URL」,“井”号后内容的简称「hash部分」

现在,虽然经发展,现代浏览器(提供新historyAPI )已经支持在不刷新整个页面情况下,更改 「URL」, 但大多数 JavaScript 框架和路由库,仍使用 「hash部分」作为「前端路由」的技术基础(EM:其实也有不用)。

EM:这里出现了SPA第一个重要的逻辑组成,Router or View router;还有形式特征:复合会话(相对于只有一个交互界面的简单应用)

SPA只使用前端Router

为了支持会话导航,SPA需要使用一个独立的router组件。router组件监测 URL的「hash部分」 的更改并做出反应。URL 「hash部分」 众所知,是原用作锚点标记(有时称为跳转链接)。 当应用程序更改了 URL 「hash部分」时,例如会话页面的跳转需要时,SPA的「某种View管理系统」需要将新的View内容渲染到DOM上(通过动态组装),这种「管理系统」就是Router。URL hash需要和 view一对一,这种关系的映射是通过配置 Router 完成的。「hash部分」 之前的任何URL更改都属于「后端 Router」。根据定义,SPA 形式仅使用「 前端 Router」实现会话导航。

前端与后端路由
前端与后端路由

EM:SPA 和MPA都需要Router,因为WGP形式需要Router。

SPA前端形态

从完整上看,大多数SPA 仍由前端和后端组成的(前端不等于SPA,更不等于WGP)。过去的多页应用,后端执行了大部分应用程序逻辑,前端只是处理了面向用户交互接口很“薄”的任务,例如呈现交互输出和收集输入。 而SPA ,后端通常只剩下所谓的持久层(及它API),简单说就是一个数据库,保存会话数据(和可能程序配置数据),前端要处理所有重要程序逻辑,包括view 路由、view 动态组装和渲染,以及业务对象的建模和对持久层的访问。

React SPA 体系结构

以上是对SPA较传统MPA在形态(形式)变化的一个概述,然而并不全面,全面概述SPA的形式特征。

SPA 形式初步

WGP 理论 全称 web界面程序的理论,web界面程序静态形式属性: WGP 形式是相当的抽象的,确定它存在的形式最好的办法是「和相邻的物种比较」。和CLI程序比(GUI),和桌面富应用比(WEB),和单一应用比(SESSION 交互流程),和无记忆静态网页比(状态智能 INTEL ),和没有后端比(NET)。 以上是WGP形式的主要属性,各构造体系有相应的质料构件实现这些属性,例如view构件实现GUI。 下图展示了SPA一般的架构形态: [图] WGP形式在技术实现上(质料结构)存在多种架构/构造体系种类,例如最为流行的React类。

React SPA

在一般React 应用中,它的SPA架构有以下一些逻辑结构件:

  • The router
  • Models
  • Views (Layout and CSS)
  • View models (compositions of system models)
  • View controllers (logic and rules in the view)
  • Messaging and eventing mechanisms

Front-end router

前面概述部分已经介绍了 router 这个SPA逻辑组件——负责实现会话导航,由于SPA将原来服务器的大部分程序逻辑转到前端,web程序形态有很大的改变,「自定 router」是SPA最大一个特点和任务。router 的任务就是切换view,实现用户的会话(工作流)的导航需求。

SESSION质性

router组件实现了WGP的SESSION质性。

React Router

React 应用程序中,首选当然是 React Router 这个库了(React 本身只是一个view 库,router 组件需另外的库)。 React Router 有所有标准 router 功能。功能包括将 route 记录映射到 view(或合成的view),以及将route 记录的 hash部分分解为「route位置参数」和「查询参数(URL 中的”?”之后的所有内容) 」的功能。参数的用途很显,是泛化 view 实例创建,router可使用参数来渲染特殊的view实例(通过props for the components)。

Front-end views

图形界面程序(GP)离不开用户界面(UI),用户界面总是离不开 views。views是 SPA 最重要的基础组件,甚至是Router应用的前提。

GUI质性

views组件实现了WGP的GUI质性。

views设计技术一

一个有用的SPA一般由多个层次化的会话界面(views)组成,然而会有少量的「主views」 直接映射用户目标需求。例如,在 email 应用程序中,用户要阅读和发送email,你的「主views」 就是”inbox”和”create email”。 在大多数应用程序中,通常会为系统或业务主要对象名词创建「主views」,例如文档、邮件、订单、用户、帖子等,并为它们的每个谓词创建关联的views,例如”find”和”create/edit”。

view组件的物理依赖

与纯粹逻辑的router不同,views有物理依赖。例如WGP依赖浏览器的渲染API。

React Views

React SPA中,React本身就是一个View库,只是相对前一代SPA框架,更现代更傻瓜自动。 细致认识View组件要从两个方向来: 第一个,是其与浏览器依赖关系; 第二个,是其与M组件组合成完整的交互功能单元(IFU)的关系;

SPA的交互功能(智能强弱)可以是很简单的,例如只有交互输出;也可以是很复杂,有界面状态,有会话智能(是一个复杂会话的一步)。 SPA是实现交互功能的,但是没有人严格规定这些功能是如何组织的,例如一个APP有多个少会话,一个会话有几个会话页(前后顺序如何),一个页面有多少交互功能,一个交互功能有多深浅,这些“设计”都是基于具体应用需求,和设计师风格决定。但是有一条,功能必须分割(安排)得适当,容易开发和维护。例如MVC模式将一个较“重”交互功能(IFU)分割为MV,M其实是与V相关的,V是只相对的独立(独立的开发和维护)。IFU承载了WGP的GUI和INTELLI质性,分立后V是GUI,M则是 INTELLI。 如果IFU足够的复杂,可能还可以再分出一些“专业”的组件,例如 view controller 和 view models 。VM是界面状态,这个需求比较多。此情,M则离V更“远”,属于交互业务对象的状态(智能),通常是在服务器上持久化,实现跨越历时会话的智能。 React 本身不提供 VC和VM组件基类,VC是通用的,VM则由第三方库提供。

Front-end models

在SPA体系中,Models 是继Router和View之外,最重要的结构件;Models就是传统MVC中M,是指代应用程序数据实体(data entities)。

智能质性INTELLI

Models 构件标明了SPA(WGP)的智能质性INTELLI;

React Models

早期,没有针对 React 应用程序设计的Models库(React只是一个View),尽管Backbone 的models也是可用作此目的(因为原MVC体系被认为已经落后,故未被广泛采用)。现在有了几个Models方案专门针对 React 应用程序。 Facebook,作为React的创建者和维护者,针对传统MVC模式的耦合度太高而不适用大型SPA(MVC架构维护性差),已经设计了一个松散耦合 Models 模式,他们称之为Flux。Flux 采用所谓单向数据流模型(one-way data flow model),此模型有三个逻辑结构件:stores, actions 和 dispatcher。

Flux

Actions 只是表征系统状况的动词,表明有系统状态变更(不像执行调用的命令,有所指向而产生直接依赖);当发生 action 时,dispatcher负责统一调度,将其路由到特定的侦听者,主要是 stores。”Stores”本质上是一系列数据,可以通过action进行查询,并发出「Stores更改事件」,View则会响应这些事件——更新内部状态和重新渲染(如果有需要)。

Reflux

另一支比较流行 React Models模型,叫 Reflux。Reflux与Flux非常相似,但省略了 dispatcher。Reflux的制作者认为 dispatcher并不是特别有必要,有时候更多是多余的。 所以,Reflux中,actions 是种特殊命令,是一种具名的命令(函数调用本身就是一种具名的命令),可以直接发布或订阅。stores 直接侦听 actions,而不是通过dispatcher 进行映射;而View会响应Stores更改事件,就像Flux 体系一样。

Messaging and eventing

随着应用中的所有计算任务组件化,实现松耦合,我们需要一种通信方法来协调它们的动作,包括数据变更同步、用户交互和特殊事件的反应。

WGP质性

组件通信和事件机制不直接反映WGP质性;

React 组件通信

在React中,父组件可以通过prop与子组件进行通信。 子组件可以使用componentWillReceiveProps生命周期方法对prop更改做出反应。 但是,我们的 data stores 不是此组件层次结构的一部分,除了视图层次结构中的通讯总线外,最好有一条通用的通信总线来进行通信。

为此,我们可以在Reflux中使用 actions。 Actions 仅仅是发布-订阅事件机制。 此外,可以将actions指定为异步操作并提供一个Promise接口。 这几乎足以满足所有SPA的需求。 另外,我们可以将actions定义对象放在一个位置,以查看系统中所有动词的列表以及它们是否异步。

Other utility needs

至此,我们已经涵盖了与views管理和前端通信有关的所有内容,但是仍然缺少一个重要的部分:图中的粗体双头箭头指向前端models(现在 stores)和服务器API之间。 为此,我们实际上只需要一个简单的 AJAX 库。

AJAX 功能通常将其集成到框架和其他工具包库中,例如jQuery和Backbone,但此类库还附带了许多我们不需要的东西。 Superagent是功能齐全的AJAX库的一个很好的例子。 它干净,可链接的接口处理不同的REST动词和HTTP标头,并提供了一个promise。

考虑React是本着Unix哲学的精神,它秉承了“只做一件事情,做好一件事情”的美德。 React只做views,并且做得好。 同样,Superagent会执行HTTP请求,仅执行HTTP请求,并且处理得很好。

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *