一、什么是SPA
释义:SPA(singgle-page application),单页面应用。
SPA是一种网络应用程序或网站模型,它通过动态重写当前页面来与用户交互,这种方法避免了页面之间切换打断用户体验。
在单页面应用中,所有必要代码(HTML、JavaScript和CSS)都通过单个页面的加载而检索,或者根据需要(通常是为了响应用户操作)动态装载适当的的资源并添加到页面中。
页面在任何时间点都不会重新加载,也不会控制转移到其他页面。
举个栗子:SPA== 保温杯,而上面的 数据图片等内容 == 枸杞跟茶,保温杯的经常换茶跟枸杞,而程序员的保温杯还是原来那个。
我们熟知的js框架如react,vue,angular,ember都属于SPA。
二、什么是MPA
释义:MAP(Multi-page application),多页面应用。
在MPA中,每个页面都是一个主页面,都是独立的。
当我们访问另一个页面的时候,都需要重新加载html、css、js文件,公共文件则根据需求加载。
举个栗子:MPA==多个保温杯,对应的数据内容放在对应的单独页面中,枸杞单独放进“枸杞-保温杯”,茶单独放进“茶-保温杯”,如果你想换种东西喝就要换个保温杯。
三、SPA与MPA的区别
1.SPA(单页面应用)的优缺点
①优点:
·具有桌面应用的即时性、网站的可移植性和可访问性。
·用户体验好、快、内容的改变不需要重新加载整个页面。
·良好的前后端分离,分工更加明显。
·维护成本相对较底。
②缺点:
·不利于搜索引擎的捉取。
·首次渲染速度相对较慢。
·开发成本相对较高。
2.MPA(多页面应用)的优缺点
①优点:
·利于搜索引擎的捉取,搜索引擎优化实现方法简易。
·首次渲染速度相对较快。
·开发成本相对较低。
②缺点:
·页面间切换加载慢,不流畅,用户体验差,尤其在移动端。
·页面重复代码较多。
·维护成本相对较高。
三、实现一个SPA
1.hash 模式
核心通过监听url中的hash来进行路由跳转。
// 定义 Routerclass Router {constructor () {this.routes = {}; // 存放路由path及callbackthis.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]()}}// 使用 routerwindow.miniRouter = new Router();miniRouter.route('/', () => console.log('page1'))miniRouter.route('/page2', () => console.log('page2'))miniRouter.push('/') // page1miniRouter.push('/page2') // page2
2.history模式
history 模式核心借用 HTML5 history api,api 提供了丰富的 router 相关属性
先了解一个几个相关的api
·history.pushState 浏览器历史纪录添加记录。
·history.replaceState修改浏览器历史纪录中当前纪录。
·history.popState 当 history 发生变化时触发。
// 定义 Routerclass 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]()})}}// 使用 Routerwindow.miniRouter = new Router();miniRouter.route('/', ()=> console.log('page1'))miniRouter.route('/page2', ()=> console.log('page2'))// 跳转miniRouter.push('/page2') // page2
参考:JS每日一题(作者灰灰)