1. 程式人生 > >如何快速開發SPA應用

如何快速開發SPA應用

前言

web早已經進入了2.0時代了,如今的網頁大有往系統應用級別的方向發展的趨勢,再也不是以前的簡單展示資訊的介面了。如今很多webapp已經做到了原生應用的功能,並且運用自身的優勢逐步取代之。HTML5也很給力,對多平臺,多螢幕裝置的良好相容性使得前端工程師們在各種平臺上大顯身手。滷煮兩年前進公司接到的也是一個SPA應用的專案,也頗有些自己的心得,今日就寫篇博文,與大家分享下。

SPA

單頁 Web 應用 (single-page application 簡稱為 SPA) 是一種特殊的 Web 應用。它將所有的活動侷限於一個Web頁面中,僅在該Web頁面初始化時載入相應的HTML、JavaScript 和 CSS。一旦頁面載入完成了,SPA不會因為使用者的操作而進行頁面的重新載入或跳轉。取而代之的是利用 JavaScript 動態的變換HTML的內容,從而實現UI與使用者的互動。由於避免了頁面的重新載入,SPA 可以提供較為流暢的使用者體驗。得益於ajax,我們可以實現無跳轉重新整理,又多虧了瀏覽器的histroy機制,我們用hash的變化從而可以實現推動介面變化。從而模擬元素客戶端的單頁面切換效果:

優缺點

SPA被人追捧是有道理的,但是它也有不足之處。當然任何東西都有兩面性,以下是滷煮總結的一些目前SPA的優缺點:

優點:

1.無重新整理介面,給使用者體驗原生的應用感覺

2.節省原生(android和ios)app開發成本

3.提高發布效率,無需每次安裝更新包。這個對於ios開發人員來說印象尤其深吧。

4.容易藉助其他知名平臺更有利於營銷和推廣

5.符合web2.0的趨勢

缺點:

1.效果和效能確實和原生的有較大差距

2.各個瀏覽器的版本相容性不一樣

3.業務隨著程式碼量增加而增加,不利於首屏優化

4.某些平臺對hash有偏見,有些甚至不支援pushstate。(你懂的)

5.不利於搜尋引擎抓取

框架

一種開發模式火起來之後,對應的框架會隨之而起。像近幾年比較火的angularJS,是目前中最流行的mvvm框架,非常適合做SPA;與之類似的還有vueJS,滷煮在專案中也用過,相對於前者比較輕量。還有早一些的backbone,提供最基本的mvc模式,其他的模組大小和細節得自己決定。最早接觸的應該是extjs吧,這頭超級巨無霸在很早的時候被用來建立企業後臺應用,如今也跟著時代的變化做出了很多的改進。等等這些框架也好,庫也好,都旨在為了更好的構建SPA應用而生的,它們優缺點滷煮就不在此一一提了。

hash值

在此處提到一個比較重要的概念:URL中的井號。其實它只是瀏覽地址中的一個特殊符號。在以前,我們經常用它來定位文件位置。例如以下程式碼:

<a href="target">go target</a>
......
<div id="target">i am target place</div>

點選a連結,文件會滾動到id為target的div的可視區域上面去。hash除了這個功能還有另一一種含義:指導瀏覽器的行為但不上傳到伺服器。大家都知道,改變url中的任何一個字元都會導致瀏覽器重新請求伺服器,除了#號後面那段字元之外。所以,簡而言之我們可以這樣理解:改變#後面的值不觸發網頁過載,但會記錄到瀏覽器history中去。

實現原理

實現SPA的方法有很多,終歸一種遵循一種原則,介面無重新整理。如果要實現原生應用中類似許多不同頁面切換的效果,我們採用的是div切換顯示和隱藏。而驅動div顯示隱藏的方式有很多種

1.監聽位址列中hash變化驅動介面變化

2.用pushsate記錄瀏覽器的歷史,驅動介面傳送變化

3.直接在介面用普通事件驅動介面變化

前兩種方式較為普遍,因為它們的變化記錄瀏覽器會儲存在history中,可以通過回退/前進按鈕找回,或者history物件中的方法控制。最後一種方法是用普通事件驅動的,沒有改變瀏覽器的history物件,所以一旦使用者按了返回按鈕將會退到瀏覽器的主介面。所以,一般採用前兩種方式。值得一提的是,在不支援hash監聽和pushsate變化的瀏覽器中可以考慮用延時函式,不停得去監聽瀏覽器位址列中url發生的變化,從而驅動介面變化。

從零開始

滷煮在很久之前的一篇博文用pushstate的變化做了一個小小的示例,大家可以在之前的博文中找到它。在這裡,我們用監聽hash變化的方式展示SPA是怎麼樣執行工作的,同時從零開始,搭建一個基礎的SPA。幫助大家理解簡單的單介面應用的原理。

首先,我們畫出三個div,它們實際上是作為三個介面存在介面上的,body作為介面外框容器,限制著它們的大小。為了給每個介面配對一個hash地址,我們給每個div配一個id,講hash地址與對應的選擇器(id、class)建立連結關係,從而可以從hash變化值中操作介面。

<body>
  <div id="A" class="a J-A">A</div>
  <div id="B" class="b J-B">B</div>
  <div id="C" class="c J-C">C</div>
</body>

接下來,為它們新增樣式,每個div都是全屏的,一開始只有A介面顯示,其他的都隱藏之:

    body {
      height: 500px;
      width: 100%;
      margin: 0;
      padding: 0;
    }
    div {
      width: 100%;
      height: 100%;
      position: absolute;
      font-size: 500px;
      text-align: center;
      display: none;
    }
    .a {
        background-color: pink;
        display: block;
    }
    .b {
      background-color: red;
    }
    .c {
    background-color: gray;
    }

現在我們給網頁新增上行為,首先需要知道的一點是,hash指即位址列中#號後面的字串,它的改變不會引起介面的重新整理,但是會出發onhashchange事件,我們要做的就是監聽這個事件:

function hashChanged(hashObj) {
  //變化之後的url
  var newhash = hashObj.newURL.split('#')[1];
  //變化之前的url
  var oldhash = hashObj.oldURL.split('#')[1];
  //將對應的hash下介面顯示和隱藏
  document.getElementById(oldhash).style.display = 'none';
  document.getElementById(newhash).style.display = 'block';
}
//監聽路由變化
window.onhashchange = hashChanged;

目前,只需要以上的程式碼,我們便可以完成一個最簡單的SPA,通過位址列的變化,介面會相應地變化。當然,除了手動在位址列裡面改變hash的變化,我們也可以用程式碼改變它的變化,從而推動介面變化,下面是兩種方式的效果圖:

可以看到,左邊是在瀏覽器中直接修改hash引起了介面的變化,而右邊則是通過程式碼控制介面變化。這兩種方式都可以在history中留下痕跡,從而當我們店家回退/前進按鈕的時候追溯到之前的介面去。有些平臺不允許我們去手動修改位址列,(比如微信),那麼我們一般採用第二種方式即可。況且,比較少的使用者會去修改位址列。

下面貼出所有的程式碼:

<!DOCTYPE html>
<html>
<head>
  <title></title>
  <style type="text/css">
    body {
      height: 500px;
      width: 100%;
      margin: 0;
      padding: 0;
    }
    div {
      width: 100%;
      height: 100%;
      position: absolute;
      font-size: 500px;
      text-align: center;
      display: none;
    }
    .a {
        background-color: pink;
        display: block;
    }
    .b {
      background-color: red;
    }
    .c {
    background-color: gray;
    }
  </style>
</head>
<body>
  <div id="A" class="a J-A">A</div>
  <div id="B" class="b J-B">B</div>
  <div id="C" class="c J-C">C</div>
</body>
<script type="text/javascript">
function hashChanged(hashObj) {
  //變化之後的url
  var newhash = hashObj.newURL.split('#')[1];
  //變化之前的url
  var oldhash = hashObj.oldURL.split('#')[1];
  //將對應的hash下介面顯示和隱藏
  document.getElementById(oldhash).style.display = 'none';
  document.getElementById(newhash).style.display = 'block';
}
//監聽路由變化
window.onhashchange = hashChanged;
</script>
</html> 

SEO優化

由於我們在處理單頁應用的時候頁面是不重新整理的,所以會導致我們的網頁記錄和內容很難被搜尋引擎抓取到。搜尋引擎抓取頁面首先要遵循http協議,可是#不是協議內的內容。而實際上也是這樣,我們沒有見過搜尋引擎的搜尋結果中,哪一條記錄可以快速定位到網頁內的某個位置的。解決的方法是用 #!號代替#號,因為谷歌會抓取帶有#!的URL。(Google規定,如果你希望Ajax生成的內容被瀏覽引擎讀取,那麼URL中可以使用"#!"(這種URL在一般頁面一般不會產生定位效果)),這樣我們可以解決ajax的不被搜尋引擎抓取的問題。在vueJs裡面,我們可以看到作者就是這樣做的。

結束

以上就是利用hash原理實現的一個很簡單的SPA。當然,要實現專案中的單頁應用,還有很多工作要做。比如傳參,動畫,非同步資源載入的問題都是需要解決的。滷煮此處只是示範了一個很簡單的例子,希望在做不復雜又不想引入其他框架的同學提供一點思路。另外單頁雖好,但不要亂用哦,根據專案的具體需求制定對應的解決方案而不是一味的追潮逐流。

參考資料

基於MVC的JavaScript Web富應用開發

相關推薦

如何快速開發SPA應用

前言 web早已經進入了2.0時代了,如今的網頁大有往系統應用級別的方向發展的趨勢,再也不是以前的簡單展示資訊的介面了。如今很多webapp已經做到了原生應用的功能,並且運用自身的優勢逐步取代之。HTML5也很給力,對多平臺,多螢幕裝置的良好相容性使得前端工程師們在各種平臺上大顯身手。滷煮兩年前進公司接到的

Vue-cli開發SPA應用(試用初學者)

lang 淘寶 web 系統 版本 window系統 檢查 運行 pri 使用Vue開發SPA(單頁面應用)估計各位博友都耳熟能詳了,這裏簡單概要一下使用vue-cli快速開發單頁面應用。本博文以window系統為例(雖然用的是Mac操作的,考慮到大多數博友是用window

使用 dva + antd 快速開發react應用

pan dem webpack mount api setup require install state 使用 dva + antd 快速開發react應用 版本說明: 註意:dva的版本是0.9.2 $ node -v v10.2.1 $ npm -v 5.6.0

快速開發跨平臺應用之Xamarin技術

  Xamarin 介紹   Xamarin 是一個允許開發人員有效建立可跨 iOS、Android、Windows 應用程式的開發工具集。Xamarin是免費且開源的,遵循 MIT (麻省理工學院許可證)協議,在github上的地址為:https://github.com/x

是時候開始用C 快速開發移動應用

                                                                                                    從2015年接觸Xamarin到至今已經2個年頭,我對Xamarin的技能沒有長進多少,但它卻已經足夠成熟到在

快速開發應用?你需要知道這5大神器

快應用,是包括華為、小米、OPPO、VIVO等10家中國手機廠商共同推出的新一代應用生態。 去年微信小程式日活從0增長到1.7億,抓住這撥紅利的創業者都拿到了各種高估值融資。 除了微信和9家聯盟,包括百度在內的所有巨頭今年都會推出自己的動態App平臺,整體動態App市場的日活預計增長到4億。

Vue-cli開發SPA應用(適用初學者)

使用Vue開發SPA(單頁面應用)估計各位博友都耳熟能詳了,這裡簡單概要一下使用vue-cli快速開發單頁面應用。本博文以window系統為例(雖然用的是Mac操作的,考慮到大多數博友是用window開發),Mac系統類似,不多贅述。 環境要求node 6.0以上(不要

使用Flask快速開發WEB應用-第二篇:Blueprint模組的應用

轉自:http://www.easywu.com/?p=306 看了之後可以對Blueprint的用法和程式的框架有所瞭解。 一個網站根據不同的功能可能會分為多個不同的模組,如果把所有功能都寫在一個檔案裡,後期將會很難維護。上一篇裡面講到了怎樣構建一個最小的Flask

基於Django快速開發Web 應用

      專案建立好後,就可以繼續在命令提示符下將當前路徑轉換為C:\mywebapp,然後執行命令manage.pystartappmessageboard 建立一個名為messageboard的新應用,該命令執行後會在C:\mywebapp 下生成應用資料夾messageboard,並在此資料夾下建立三

Node實戰(第2季)5 基於Koa快速開發Web應用

   講解ES6中生成器、yield,以及Node.js下一代Web開發框架--Koa及其中介軟體的用法。 5.1 ES6時代的來臨    ECMAScript6,簡稱ES6,也稱作ECMAScript2015,於2015年6月正式定稿。ES6是一次重大升級,是自2009年

使用create-react-app快速開發React應用

React是一個JavaScript語言的工具庫,在這個JavaScript工具鋪天蓋地的時代,沒有意外,首先需要安裝Node.js和npm,React本身並不依賴Node.js,但是我們開

快速開發android應用6-實現scrollview和recyclerview同方向滑動

概述 本次快速開發Android應用系列,是基於課工場的公開課高效Android工程師6周培養計劃,記錄微服私訪APP的整個開發過程以及當中碰到的問題,供日後學習參考。 上一篇我們主要實現通過picasso獲取伺服器圖片,並通過輪播圖的形式展現以及實現個

Linux利用curl庫快速開發http應用

    熟悉Linux系統的人不可能不知道curl的鼎鼎大名吧?curl是將http請求封裝的相當好的庫,詳見http://curl.haxx.se/,我們可以利用curl實現快速http請求的開發。     在Linux系統下,你只需要sudo apt-get insta

如何快速開發Winform應用系統

在實際的業務中,往往還有很多需要使用Winform來開發應用系統的,如一些HIS、MIS、MES等系統,由於Winform開發出來的系統介面友好,響應快速,開發效率高等各方面原因,還有一些原因是獨立的WInform應用系統方便部署使用,可以快速的在內部系統中安裝使用,小型的系統往往不需要涉及到雲服務等分散式的

BeetleX使用bootstrap5開發SPA應用

    在早期版本BeetleX.WebFamily只提供了vuejs+element的整合,由於element只適合PC管理應用開發相對於移動應用適配則沒這麼方便。在新版本元件集成了bootstrap5可以更好地適配移動Web應用;同時也集成了Fontawesome和

推薦H5應用快速開發UI庫

好的 部分 文件 輕量 服務 ui組件 oba obi 基於 Framework7(阿裏巴巴)、SUI(淘寶)、MUI( dcloud-HBuilder)、WeUI(微信)、Frozen UI(騰訊手機QQ)、GMU(百度)、Amaze UI(雲適配) 等… Framewo

前端入門:快速開發基於 HTML5 網絡拓撲圖應用

簡寫 我們 圖片路徑 urn setattr bsp left return 管理 計算機網絡的拓撲結構是引用拓撲學中研究與大小,形狀無關的點、線關系的方法。把網絡中的計算機和通信設備抽象為一個點,把傳輸介質抽象為一條線,由點和線組成的幾何圖形就是計算機網絡的拓撲結構。網絡

android懸浮球實現各種功能、快速開發框架、單詞、筆記本、應用市場應用等源碼

jpeg 源碼 新聞 thread 並不是 類型 and 所有 大小 Android精選源碼 懸浮球,實現一鍵靜音,一鍵鎖頻,一鍵截屏等功能 一個Android快速開發框架,MVP架構 Android QQ小紅點的實現源碼 android一款單詞應用完整app源碼

10天Hadoop快速突擊(3)——開發MapReduce應用程式

開發MapReduce應用程式一、系統引數的配置1.通過API對相關元件的引數進行配置這些API被分成了一下幾個部分:org.apache.hadoop.conf:定義了系統引數的配置檔案處理APIorg.apache.hadoop.fs:定義了抽象的檔案系統APIorg.a

推薦手機H5應用快速開發 UI庫(Framework7、SUI(淘寶)、MUI、WeUI(微信)、GMU(百度)、Frozen UI(QQ))

推薦手機H5應用快速開發 UI庫 Framework7(阿里巴巴)、SUI(淘寶)、MUI( dcloud-HBuilder)、WeUI(微信)、Frozen UI(騰訊手機QQ)、GMU(百度)、Amaze UI(雲適配) 等… Framework