單頁面應用: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的實現