前端单页面富应用(SPA)的实现
一、 什么是单页面富应用?
单页面应用:Single Page Application
- 概念:Web应用即使不刷新也在不同的页面间切换,解决浏览器前进、后退等机制被破坏等问题。并且页面访问会被浏览器保存。
 - 实现方法:
- Node+Html5实现
 - React/Vue等MVVM框架
 
 
二、单页面应用的实现
1. Node+Html5
H5实现单页面应用为什么需要Node?
虽然使用的是H5的新特性:History API,但是单页面应用实际上是利用路由变化从而判断是否改变内容。这里仅用node开启服务,url地址的变化采用的是H5的History API。
步骤
- 使用express自动化构建项目
 
express myAppName
- 去掉多余路由文件(user.js),修改App.js渲染文件的类型(默认jade => html)
 
app.engine('html',require('ejs').renderFile);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');
- 编写index.html
项目效果:点击相应button,url路由和底部内容都会相应变化

 
//html
<div class="appWried">
    <div class="appBtn">
        <button>PAGE1</button>
        <button>PAGE2</button>
        <button>PAGE3</button>
    </div>
    <div class="appContent">
        暂无内容
    </div>
</div>
<script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script>
$(function(){
    var button = $('.appBtn button');
    button.click(function(){
        let route = $(this).text(); //获取按钮的文本
        //把按钮内容当做url路由导航
        pageChange(route);
        //history.pushState 添加浏览器历史
        history.pushState('','',route)   //state回调函数传入对象 title新页面标题 url新页面路径,地址栏会显示新路径
    })
    //根据点击或者路由改变相应的页面内容
    function pageChange(route){
        console.log(route);
        button.removeClass('active');
        //filter() 方法将匹配元素集合缩减为匹配指定选择器的元素
        button.filter(function(){
            return $(this).text() == route;
        }).addClass('active');
        //改变内容
        $('.appContent').text(`我是${route}`);
    }
})
</script>
这里为了方便,我采用了JQuery的官方CDN。
pushState是html5的History新增的。
window.history.pushState(json,title,url)
// 状态对象:记录历史记录点的额外对象,可以为空
// 页面标题:目前所有浏览器都不支持, 可以为空
// 可选的url:浏览器不会检查url是否存在,只改变url,url必须同域,不能跨域
此外,pushState经常搭配监听历史记录点事件window.onpopstate来监听url的变化。并且可以获取存储在该历史记录点的状态对象,也就是pushState存储的json对象。例如:
window.addEbentListener('popState',function(){
    console.log('url改变')
})
2. React
现在很多前端框架都追求组件化开发、组件化复用。组件化和单页面应用非常配。所以React、Vue等也常常用于SPA的开发。
使用React开发SPA至少需要用到:React、React-router(-dom)
项目使用的是React-router-dom。
react-router 和 react-router-dom 的不同之处就是后者比前者多出了 这样的 DOM 类组件。并且react-router-dom是其升级版,可以更快更新,react-router即将废弃.
项目效果:

//views/index.js
import React from 'react';
import { Link,withRouter } from 'react-router-dom'
import './style.css'
class AppPage extends React.Component{
    constructor(arg){
        super(arg)
        this.state={}
    }
    render(){
        let appContent = ''
        if(this.props.history.location.pathname){
            appContent = this.props.history.location.pathname
        }else{
            appContent = '暂无内容'
        }
        return(
            <div className="appWried">
                <div className="appBtn">
                    <Link to="/PAGE1">
                        <button className={ this.props.history.location.pathname === '/PAGE1' ? 'active' : '' }>PAGE1</button>
                    </Link>
                    <Link to="/PAGE2">
                        <button className={ this.props.history.location.pathname === '/PAGE2' ? 'active' : '' }>PAGE2</button>
                    </Link>
                    <Link to="/PAGE3">
                        <button className={ this.props.history.location.pathname === '/PAGE3' ? 'active' : '' }>PAGE3</button>
                    </Link>
                </div>
                <div className="appContent">
                    {appContent}
                </div>
            </div>
        )
    }
}
AppPage = withRouter(AppPage); //通过withRouter给AppPage组件注入路由信息
export default AppPage;
//App.js
import AppPage from './views/index'
<Router>
    ...
    <AppPage />
    ...
</Router>
注意:使用了route、withRouter需要在app.js最外层嵌套Router组件
至此,利用React实现简单的SPA就完成了!
三、总结
单页面应用开发在前端已经是不可或缺了。单页面应用既有它的优点,也有它的缺点。
优点:
- 良好的交互体验
 
用户不需要重新刷新页面,获取数据也是通过Ajax异步获取,页面显示流畅。
- 良好的前后端工作分离模式
 
单页Web应用可以和RESTful规约一起使用,通过REST API提供接口数据,并使用Ajax异步获取,这样有助于分离客户端和服务器端工作。更进一步,可以在客户端也可以分解为静态页面和页面交互两个部分。
- 减轻服务器压力
 
服务器只用出数据就可以,不用管展示逻辑和页面合成,吞吐能力会提高几倍;
- 共用一套后端程序代码
 
不用修改后端程序代码就可以同时用于Web界面、手机、平板等多种客户端;
缺点:
- SEO难度较高
 
由于所有的内容都在一个页面中动态替换显示,所以在SEO上其有着天然的弱势,所以如果你的站点对SEO很看重,且要用单页应用,那么就做些静态页面给搜索引擎用吧。
- 前进、后退管理
 
由于单页Web应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理,当然此问题也有解决方案,比如利用URI中的散列+iframe实现。
- 初次加载耗时多
 
为实现单页Web应用功能及显示效果,需要在加载页面的时候将JavaScript、CSS统一加载,部分页面可以在需要的时候加载。所以必须对JavaScript及CSS代码进行合并压缩处理,如果使用第三方库,建议使用一些大公司的CDN,因此带宽的消耗是必然的。
解决SPA的SEO(搜索引擎优化):SSR(服务器渲染)
SSR:服务器将每个要展示的页面都运行完成后,将整个相应流传送给浏览器,所有的运算在服务器端都已经完成,浏览器只需要解析 HTML 就行。
具体SSR作用下次介绍~
附上上面代码的github:SPA的实现
前端单页面富应用(SPA)的实现的更多相关文章
- Vue(6)- Vue-router进阶、单页面应用(SPA)带来的问题
		
一.Vue-router进阶 回顾学过的vue-router,并参考官方文档学习嵌套路由等路由相关知识. 二.单页面应用(SPA)带来的问题 1.虽然单页面应用有优点,但是,如果后端不做服务器渲染(h ...
 - Vue --6 router进阶、单页面应用(SPA)带来的问题
		
一.Vue-router进阶 回顾学过的vue-router,并参考官方文档学习嵌套路由等路由相关知识. 二.单页面应用(SPA)带来的问题 1.虽然单页面应用有优点,但是,如果后端不做服务器渲染(h ...
 - 单页面应用(SPA)
		
此篇我们来瞅一瞅SPA,啥是SPA啊,实际上一点也不神秘,就是单页应用,可能有的同学又会问了,啥是单页面应用,别着急,我们慢慢来看 首先我们先来了解一下单页应用出现背景 背景: 在早期的 Web 应用 ...
 - 单页面应用程序(SPA)
		
一.概念 ①在一个页面上实现网站的大部分功能,就是单页面应用程序,是一种常见的网页开发模式. ②整个网站就只有一个Html文件,每次在切换页面时,不需要请求服务器,只要通过本地的js来切换即可.这样可 ...
 - Vue-router进阶、单页面应用(SPA)带来的问题
		
一 . vue-router 进阶 回顾学过的vue-router,并参考官方文档学习嵌套路由等路由相关知识. 二 . 单页面应用(SPA)带来的问题 1 . 虽然单页面应用有优点 , 但是,如果后端 ...
 - Vue 单页面应用 SEO   SPA   single page application advantages and disadvantages
		
处理 Vue 单页面应用 SEO 的另一种思路 - muwoo - 博客园 https://www.cnblogs.com/tiedaweishao/p/7493971.html SPA网站SEO完美 ...
 - 单页面应用(SPA)重新部署后,正在浏览的页面如何更新缓存?
		
当单页面的系统在重新部署更新时,此时正在浏览网页,并且已经在网页内的用户,始终会使用老的js与css文件,一直在使用已经缓存了的静态资源. 所有的缓存问题焦点都在index.html上,只要index ...
 - 单页面应用(spa)引入百度地图(Cannot read property 'dc' of undefined)
		
难点介绍 引入百度地图的时候,用原生的获取不到dom节点. ( var mapEle = document.getElementById(testApi): var map = new BMap.Ma ...
 - SPA单页面应用和MPA多页面应用(转)
		
原文:https://www.jianshu.com/p/a02eb15d2d70 单页面应用 第一次进入页面时会请求一个html文件,刷新清除一下,切换到其他组件,此时路径也相应变化,但是并没有新的 ...
 
随机推荐
- spring 事物的一些理解
			
推荐一个我认为Spring事物写得很好的文章. 文章链接:http://www.codeceo.com/article/spring-transactions.html 文章作者:码农网 – 吴极心 ...
 - Chrome表单自动填充如何取消(暂时可行的解决办法)
			
做项目时一直遇到一个问题,那就是用chrome测试的时候页面上的表单一直会自动填充,并且伴有黄色的背景颜色,有时候感觉很方便,有时候又很想去掉. 之前也多次寻找过方法,但是网上的方法都差不多,很多都是 ...
 - Codeforce 697A - Pineapple Incident
			
Ted has a pineapple. This pineapple is able to bark like a bulldog! At time t (in seconds) it barks ...
 - 每日linux命令学习-rpm命令
			
rpm命令 rpm是一款强大的Redhat软件包管理工具,可创建.安装.查询.验证.升级和卸载每个软件包,软件包是存储文件,包括需要安装的文件和名称.版本.说明等报信息. rpm默认支持7种操作模式, ...
 - Pytorch的torch.cat实例
			
import torch 通过 help((torch.cat)) 可以查看 cat 的用法 cat(seq,dim,out=None) 其中 seq表示要连接的两个序列,以元组的形式给出,例如:se ...
 - 抓取awr、语句级awr、ashrpt
			
exec dbms_workload_repository.create_snapshot();--调用MMON进程立即收集快照 生成AWR报告@?/rdbms/admin/awrrpt.sql; 9 ...
 - Fiddler抓取手机端(ios+android)APP接口数据(http+https)
			
(1)android 环境要求: PC机和手机连接在同一网络下 工具下载地址: Fiddler网上可以下载,自行下载.注意:需要安装fiddlercertmaker(网上自行下载)进行认证 配置步骤: ...
 - JAVA基础部分   JDK和JRE以及JVM
			
第一部分: 一.dos命令 *快捷查看电脑ip: Win + R进入cmd;输入ipconfig/all查看IPv4:192.168.0.xxx(首选); 基本命令: cd进入目录:d: 直接进入盘符 ...
 - bzoj 2527 Meteors - 整体二分 - 树状数组
			
Description Byteotian Interstellar Union (BIU) has recently discovered a new planet in a nearby gala ...
 - VC++ 利用PDB和dump文件定位问题并进行调试
			
转载:https://blog.csdn.net/zfs_kuai/article/details/43646665 转载:https://blog.csdn.net/i_chaoren/articl ...