我们先来看一下在百科上面的解释吧,emmmm,一般呢,我每次搜索一些不懂的词,都会习惯先去看百科里面的解释,反正我从来都不奢望能看懂,只是指望有个大概的框架的,哈哈~
“单页面应用(SPA:single-page application),就是只有一张Web页面的应用,是加载单个HTML页面并在用户与应用程序交互时动态更新该页面的web应用程序。” -- from 百度百科
“单页应用(英语:single-page application,缩写 SPA)是一种网络应用程序或网站的模型,它通过动态重写当前页面来与用户交互,而非传统的从服务器重新加载整个新页面。这种方法避免了页面之间切换打断用户体验,使应用程序更像一个桌面应用程序。在单页应用中,所有必要的代码(HTML、JavaScript和CSS)都通过单个页面的加载而检索,或者根据需要(通常是为响应用户操作)动态装载适当的资源并添加到页面。尽管可以用位置散列或HTML5历史API来提供应用程序中单独逻辑页面的感知和导航能力,但页面在过程中的任何时间点都不会重新加载,也不会将控制转移到其他页面。与单页应用的交互通常涉及到与网页伺服器后端的动态通信。” -- from 维基百科
是不是云里雾里?
What:SPA是什么?
简单点~说话的方式简单点~
- 整个 webapp 只有单个HTML文件,所有操作都在这张页面上完成,由 js 来按需加载 HTML、CSS 和 JS
- 多个HTML页面文件的幻觉呢,都是通过 js 来操作 dom 节点来动态实现的(所以跳转到一个新页面实质上就是,删除本页面 dom 节点,新增新页面 dom 节点。从这里呢引出了一个虚拟 dom 的概念,这个以后会说到的)
- 不同页面之间的跳转幻觉呢,也是通过 js 控制 hash 或者 history api(go、back) 来进行路由 (这就是一个更加明确前后端分离的卖点了)
- 最后通过 ajax 拉取数据实现响应功能
特点:
- 速度:更好的用户体验,让用户在 webapp 感受到 native app 的速度和流畅
- MVVM:经典的 MVVM 开发模式,,前后端各负其责
- ajax:业务逻辑全部都在本地操作,数据都需要通过 ajax 同步提交
- 路由:在 URL 中采用 # 号来作为当前视图的地址(http://xxx.com/#/),改变 # 号后的参数来载入不同的页面片段。(页面并不会重载!)
优点:
- 分离前后端关注点,前端负责界面显示,包括页面跳转逻辑;后端则只负责数据管理(存储和计算),各司其职,不会把前后端的逻辑混杂在一起。
- 减轻服务器的压力,服务器只用出数据就可以,不用管展示逻辑和页面合成,吞吐能力提高好几倍。
- 同一套后端程序代码/接口,可以多处复用,不仅是同一个应用不用修改就可以用于web界面、手机、平板等多种客户端,同时也可以复用在不同应用上。
缺点:
- SEO问题:对 SEO 不友好,但是可以通过 Prerender 等技术解决一部分
- 前进、后退、地址栏等,需要程序进行管理
- 书签,需要程序来进行控制
Why:为什么要用SPA?
SPA 与 MPA 的对比:
单页应用程序(SPA) | 多页应用程序(MPA) | |
SPA如图 :
MPA如图 : | ||
应用组成 | 一个外壳页面和多个页面片段组成 | 由多个完整页面构成 |
跳转方式 | 片段跳转:把一个页面片段删除或者隐藏,加载另一个页面片段并显示出来。这是片段之间的模拟跳转,并没有离开壳页面 | 页面跳转:从一个页面跳转到另一个页面 |
URL模式 | http://xxx.com/index.html#page1 http://xxx.com/index.html#page2 | http://xxx.com/page1.html http://xxx.com/page2.html |
刷新方式 | 页面片段局部刷新 | 整页刷新 |
跳转后公共资源是否重载 | 否 | 是 |
页面间传递数据 | 因为在一个页面上,所以可以设置全局常量来记录这些固定的数据,所以页面片段传递数据很容易实现 | 依赖 URL, cookie, localStorage,实现麻烦 |
页面切换转场画面 | 容易实现 | 无法实现 |
用户体验 | 页面片段间切换快,转场画面佳,用户体验好,包括在移动设备上 | 页面间切换加载慢,不流畅,用户体验差,特别是在移动设备上 |
SEO | 需要单独方案做,有点麻烦 | 可以直接做 |
特别适用范围 | 对体验要求高的应用,特别是移动应用 | 需要对搜索引擎友好的网站 |
开发难度 | 高一些,MVVM 模式框架 | 低一些,框架选择容易 |
维护成本 | 相对容易 | 相对复杂 |
How:怎么实现 SPA ?
MVVM框架: 诸如 AngularJS、Vue.js、React、Ember.js、Meteor.js、ExtJS 等面向网页浏览器的 JavaScript 框架采纳了单页应用(SPA)原则。
目前听到最多的还是前面的三大框架:Angular、Vue 和 React。
当然,本系列我们还是主要讨论Vue,而且我也还要一边巩固熟练使用 Vue ,一边 Angular 新手上路,大家一起加油鸭!
#一、什么是SPA
SPA(single-page application),翻译过来就是单页应用SPA是一种网络应用程序或网站的模型,它通过动态重写当前页面来与用户交互,这种方法避免了页面之间切换打断用户体验在单页应用中,所有必要的代码(HTML、JavaScript和CSS)都通过单个页面的加载而检索,或者根据需要(通常是为响应用户操作)动态装载适当的资源并添加到页面页面在任何时间点都不会重新加载,也不会将控制转移到其他页面举个例子来讲就是一个杯子,早上装的牛奶,中午装的是开水,晚上装的是茶,我们发现,变的始终是杯子里的内容,而杯子始终是那个杯子结构如下图
我们熟知的JS框架如react,vue,angular,ember都属于SPA
#二、SPA和MPA的区别
上面大家已经对单页面有所了解了,下面来讲讲多页应用MPA(MultiPage-page application),翻译过来就是多页应用在MPA中,每个页面都是一个主页面,都是独立的当我们在访问另一个页面的时候,都需要重新加载html、css、js文件,公共文件则根据需求按需加载如下图
#单页应用与多页应用的区别
单页面应用(SPA) | 多页面应用(MPA) | |
组成 | 一个主页面和多个页面片段 | 多个主页面 |
刷新方式 | 局部刷新 | 整页刷新 |
url模式 | 哈希模式 | 历史模式 |
SEO搜索引擎优化 | 难实现,可使用SSR方式改善 | 容易实现 |
数据传递 | 容易 | 通过url、cookie、localStorage等传递 |
页面切换 | 速度快,用户体验良好 | 切换加载资源,速度慢,用户体验差 |
维护成本 | 相对容易 | 相对复杂 |
#单页应用优缺点
优点:
- 具有桌面应用的即时性、网站的可移植性和可访问性
- 用户体验好、快,内容的改变不需要重新加载整个页面
- 良好的前后端分离,分工更明确
缺点:
- 不利于搜索引擎的抓取
- 首次渲染速度相对较慢
#三、实现一个SPA
#原理
- 监听地址栏中hash变化驱动界面变化
- 用pushsate记录浏览器的历史,驱动界面发送变化
#实现
#hash模式
核心通过监听url中的hash来进行路由跳转
// 定义 Router
class Router {
constructor () {
this.routes = {}; // 存放路由path及callback
this.currentUrl = '';
// 监听路由change调用相对应的路由回调
window.addEventListener('load', this.refresh, false);
window.addEventListener('hashchange', this.refresh, false);
}
route(path, callback){
this.routes[path] = callback;
}
push(path) {
this.routes[path] && this.routes[path]()
}
}
// 使用 router
window.miniRouter = new Router();
miniRouter.route('/', () => console.log('page1'))
miniRouter.route('/page2', () => console.log('page2'))
miniRouter.push('/') // page1
miniRouter.push('/page2') // page2
#history模式
history 模式核心借用 HTML5 history api,api 提供了丰富的 router 相关属性先了解一个几个相关的api
- history.pushState 浏览器历史纪录添加记录
- history.replaceState修改浏览器历史纪录中当前纪录
- history.popState 当 history 发生变化时触发
// 定义 Router
class Router {
constructor () {
this.routes = {};
this.listerPopState()
}
init(path) {
history.replaceState({path: path}, null, path);
this.routes[path] && this.routes[path]();
}
route(path, callback){
this.routes[path] = callback;
}
push(path) {
history.pushState({path: path}, null, path);
this.routes[path] && this.routes[path]();
}
listerPopState () {
window.addEventListener('popstate' , e => {
const path = e.state && e.state.path;
this.routers[path] && this.routers[path]()
})
}
}
// 使用 Router
window.miniRouter = new Router();
miniRouter.route('/', ()=> console.log('page1'))
miniRouter.route('/page2', ()=> console.log('page2'))
// 跳转
miniRouter.push('/page2') // page2
#四、题外话:如何给SPA做SEO
下面给出基于Vue的SPA如何实现SEO的三种方式
- SSR服务端渲染
将组件或页面通过服务器生成html,再返回给浏览器,如nuxt.js
- 静态化
目前主流的静态化主要有两种:(1)一种是通过程序将动态页面抓取并保存为静态页面,这样的页面的实际存在于服务器的硬盘中(2)另外一种是通过WEB服务器的 URL Rewrite的方式,它的原理是通过web服务器内部模块按一定规则将外部的URL请求转化为内部的文件地址,一句话来说就是把外部请求的静态地址转化为实际的动态页面地址,而静态页面实际是不存在的。这两种方法都达到了实现URL静态化的效果
- 使用Phantomjs针对爬虫处理
原理是通过Nginx配置,判断访问来源是否为爬虫,如果是则搜索引擎的爬虫请求会转发到一个node server,再通过PhantomJS来解析完整的HTML,返回给爬虫。下面是大致流程图
什么是单页面?
概念:就是只有一张Web页面的应用。单页面程序SPA是加载单个HTML页面并在用户与应用程序交互时动态更新页面的Web应用程序
单页面的优缺点