单页面应用:Single Page Applicationcss
H5实现单页面应用为何须要Node?
虽然使用的是H5的新特性:History API,可是单页面应用其实是利用路由变化从而判断是否改变内容。这里仅用node开启服务,url地址的变化采用的是H5的History API。html
express myAppName
app.engine('html',require('ejs').renderFile); app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'html');
//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对象。例如:html5
window.addEbentListener('popState',function(){ console.log('url改变') })
如今不少前端框架都追求组件化开发、组件化复用。组件化和单页面应用很是配。因此React、Vue等也经常用于SPA的开发。
使用React开发SPA至少须要用到:React、React-router(-dom)node
项目使用的是React-router-dom。
react-router 和 react-router-dom 的不一样之处就是后者比前者多出了这样的 DOM 类组件。而且react-router-dom是其升级版,能够更快更新,react-router即将废弃. react
项目效果:
jquery
//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组件git
至此,利用React实现简单的SPA就完成了!github
单页面应用开发在前端已是不可或缺了。单页面应用既有它的优势,也有它的缺点。express
用户不须要从新刷新页面,获取数据也是经过Ajax异步获取,页面显示流畅。
单页Web应用能够和RESTful规约一块儿使用,经过REST API提供接口数据,并使用Ajax异步获取,这样有助于分离客户端和服务器端工做。更进一步,能够在客户端也能够分解为静态页面和页面交互两个部分。
服务器只用出数据就能够,不用管展现逻辑和页面合成,吞吐能力会提升几倍;
不用修改后端程序代码就能够同时用于Web界面、手机、平板等多种客户端;
因为全部的内容都在一个页面中动态替换显示,因此在SEO上其有着自然的弱势,因此若是你的站点对SEO很看重,且要用单页应用,那么就作些静态页面给搜索引擎用吧。
因为单页Web应用在一个页面中显示全部的内容,因此不能使用浏览器的前进后退功能,全部的页面切换须要本身创建堆栈管理,固然此问题也有解决方案,好比利用URI中的散列+iframe实现。
为实现单页Web应用功能及显示效果,须要在加载页面的时候将JavaScript、CSS统一加载,部分页面能够在须要的时候加载。因此必须对JavaScript及CSS代码进行合并压缩处理,若是使用第三方库,建议使用一些大公司的CDN,所以带宽的消耗是必然的。
解决SPA的SEO(搜索引擎优化):SSR(服务器渲染)
SSR:服务器将每一个要展现的页面都运行完成后,将整个相应流传送给浏览器,全部的运算在服务器端都已经完成,浏览器只须要解析 HTML 就行。
具体SSR做用下次介绍~
附上上面代码的github:SPA的实现