最近一直在學習關於Vue的一些知識,由於遇到了問題,去網上查找資料,收穫頗豐,在此分享。 1. 什麼是SPA? 單頁Web應用(single page web application, SPA),就是只有一張Web頁面的應用,是載入單個HTML頁面併在用戶與應用程式交互時動態更新該頁面的Web應用程 ...
最近一直在學習關於Vue的一些知識,由於遇到了問題,去網上查找資料,收穫頗豐,在此分享。
1. 什麼是SPA?
單頁Web應用(single page web application, SPA),就是只有一張Web頁面的應用,是載入單個HTML頁面併在用戶與應用程式交互時動態更新該頁面的Web應用程式,是指在瀏覽器中運行的應用,在使用期間不會重新載入頁面。像所有的應用一樣,它旨在幫助用戶完成任務,比如“編寫文檔”或者“管理Web伺服器”。可以認為單頁應用是一種從Web伺服器載入的富客戶端。
速度:更好的用戶體驗,讓用戶在web app感受native app的速度和流暢,
MVC:經典MVC開發模式,前後端各負其責,後端只需要提供數據介面
ajax:重前端,業務邏輯全部在本地操作,數據都需要通過AJAX同步、提交。
路由:在URL中採用#號來作為當前視圖的地址,改變#號後的參數,頁面並不會重載,這個也就是哈希。
SPA也是當今網站開發技術的一種趨勢和潮流,畢竟前端三大框架不是蓋的~~,很多的傳統網站都在或者已經轉型為單頁Web應用,新的單頁Web應用網站(包括移動端平臺上面的)也雨後春筍涌現出來。
單頁Web應用和前端工程師們息息相關,因為主要的變革發生在瀏覽器端,用到的技術其實還是HTML+CSS+JavaScript,所有的瀏覽器都原生支持,當然有的瀏覽器因為具備一些高級特性,從而使得單頁Web應用的用戶體驗更上一層樓。關於單頁應用的優點和缺點,下一個問題就說。 單頁Web應用,顧名思義,就是只有一張Web頁面的應用。瀏覽器一開始會載入必需的HTML、CSS和JavaScript,之後所有的操作都在這張頁面上完成,這一切都由JavaScript來控制。因此,單頁Web應用會包含大量的JavaScript代碼,複雜度可想而知,模塊化開發和設計的重要性不言而喻。
單頁Web應用程式的優點:
1.首先,最大的好處是用戶體驗,對於內容不改動的不需要載入整個頁面。這樣做好處頗多,因為數據層是和UI的分離,可以重新編寫一個原生的移動設備應用程式而不用(對原有數據服務部分)大動干戈。
2.單頁面Web應用層程式最根本的優點是高效。它對伺服器壓力很小,消耗更少的帶寬,能夠與面向服務的架構更好地結合。
單頁Web應用程式的缺點:
雖然還有一些歷史遺留問題(大部分是針對HTML5的改進)以及SEO。如果你看中SEO,那你應該使用網站而不是Web應用。目前該技術還存在一些爭議,但這並不是重點,因為這種類型的體系架構為SAAS Web Apps提供了一個極大的可用性。
程式結構 -- 重點
單頁Web應用程式的結構很簡單:首先傳遞HTML文檔框架;然後使用JavaScript修改頁面;緊接著再從伺服器傳遞更多數據然後再修改頁面,如此迴圈。從性能的角度看,在現代瀏覽器中單頁面Web App已經能夠和普通應用程式相媲美,而且幾乎所有的操作系統都支持現代的瀏覽器。使用HTML+CSS+JavaScript編寫應用程式,能使更多的人們都加入到程式開發的行列。
這足以說明,在Web設計過程中標志著Web將呈現一種新的趨勢,它將一個分離的功能層作為API並將表示層用APP的形式體現出來(HTML5或Native)
- 單頁面+API模式比基於應用程式的HTML多重頁面更加靈活,因為底層API可用於多種不同的上下文、形式因素和設備類型。一旦網頁內置了API,能夠滿足客戶不同需求(比如合作伙伴vs最終用戶)。
- 該模式意味著本地Web應用能夠為用戶無論是基於什麼平臺提供更接近一個本地移動或桌面應用程式的體驗。
- 協議(如openAuth(oAuth))成為作為用戶授權的黃金標準已被廣泛採用,提供了一個共同的模式。從應用程式好餓內容中將單獨登錄/授權問題分離出來。也就是說用戶的身份可以從內容、功能和用戶體驗中清晰的分離出。
一個單頁面Web應用程式就是一個Web應用程式,但結構哦不同。其中最重要的是:在第一次請求的時候,所有的標記語言(HTML)就已經傳輸到客戶端,其餘的請求都通過REST API獲取JSON數據,數據的傳輸通過Web Socket API或遠程過程調用。單頁面應用程式可以說是分拆Web技術的最後一步----通過分離(css)內容,改進架構(XML和XSLT)上的靈活性,調用伺服器(AJAX)再到解壓應用程式的導航頁面結構,因此,這在Web發展中是個歷史性的轉折點。
目前這隻是單頁面Web應用開發的初期,但可以看出將單頁面應用、APIs以及JavaScript結合在一起將成為許多流行應用的規範。
所以,當被問到“HTML5是App+API?”,我們會說,“兩者皆是---”將兩者結合在一起要比以往快得多。“單頁面應用是一塊非常大的拼圖。當然,導航、歷史性和SEO等問題也成為單頁面Web應用的詬病”
單頁面應用的演進
在這裡介紹一些Hash的內容先,單頁面應用是如何實現不刷新網頁而進行跳轉的呢?
HTML中的hash(#號)
1.#的含義
#代表網頁中的一個位置。右面的自負就是代表的位置信息:如
http://localhost:8080/cbuild/index.html#one
就代表網頁index.html的one位置。瀏覽器讀取這個URL後,會自動將one位置滾動至可視區域。
為網頁制定標識符:
一是使用錨點 比如 <a name="print"></a>
二是使用id屬性,比如<div id="print"></div>
2.HTTP請求不包括#
比如: http://localhost:8081/cbuild/index.html#first
瀏覽器實際發出的請求是這樣的
GET/index.html
而不包含 #first
3.#後的字元
在第一個#後面出現的任何字元,都會被瀏覽器解讀為位置標識符。這意味著,這些字元都不會被髮送到伺服器端。
比如,下麵URL的原意是指定一個顏色值:
http://www.example.com/?color=#fff
但是,瀏覽器實際發出的請求是:
GET/?color=
Host: www.example.com
可以看到,“#fff”被省略了,只有將#轉碼為$23,瀏覽器才會將其作為實義字元處理。也就是說,上面的網址應該被寫成:
http://www.example.com/?color=%23fff
四、改變#不觸髮網頁重載
單單改變#後的部分,瀏覽器只會滾動到相應位置,不會重新載入網頁。
比如,從
http://www.example.com/index.html#location1
改變到
http://www.example.com/index.html#location2
瀏覽器不會重新向伺服器請求index.html
五、改變#會改變瀏覽器的訪問歷史
每一次改變#後的部分,都會在瀏覽器的訪問歷史中增加一個記錄,使用"後退"按鈕,就可以回到上一個位置。
這對於ajax應用程式特別有用,可以用不同的#值,表示不同的訪問狀態,然後向用戶給出可以訪問某個狀態的鏈接。
值得註意的是,上述規則對IE6和IE7不成立,它們不會因為#的改變而增加歷史記錄
六、window.location.hash讀取#值
window.location.hash這個屬性可讀可寫。讀取時,可以用來判斷網頁狀態是否改變;寫入時,則會在不重載網頁的前提下,創造一條訪問歷史記錄。
七、onhashchange事件
這是一個HTML5新增的事件,當#值發生變化時,就會觸發這個事件。IE8+、Firefox 3.6+、Chrome 5+、Safari 4.0+支持該事件。
它的使用方法有三種:
1 window.onhashchange = func; 2 <body onhashchange="func();"> 3 window.addEventListener("hashchange",func, false);
對於不支持onhashchange的瀏覽器,可以用setInterval監控location.hash的變化。
八、Google抓取#的機制
預設情況下,Google的網路蜘蛛忽視URL的#部分。
但是,Google還規定,如果你希望Ajax生成的內容被瀏覽引擎讀取,那麼URL中可以使用"#!",Google會自動將其後面的內容轉成查詢字元串_escaped_fragment_的值。
比如,Google發現新版twitter的URL如下:
http://twitter.com/#!/username
就會自動抓取另一個URL:
http://twitter.com/?_escaped_fragment_=/username
通過這種機制,Google就可以索引動態的Ajax內容。
單頁面Web應用就是根據上述的#,監控#值的改變去對應的改變頁面。
路由:頁面跳轉與模塊關係
要說起路由,那可是有很長的故事。當我們在瀏覽器上輸入網址的時候,我們就已經開始了各種路由的旅途了。
- 瀏覽器會檢查有沒有相應的功能變數名稱緩存,沒有的話就會一層層的去向 DNS伺服器 尋向,最後返回對應的伺服器的 IP 地址。
- 接著,我們請求的網站將會將由對應 IP 的 HTTP 伺服器處理,HTTP 伺服器會根據請求來交給對應的應用容器來處理。
- 隨後,我們的應用將根據用戶請求的路徑,將請求交給相應的函數來處理。最後,返回相應的 HTML 和資源文化
當我們做後臺應用的時候,我們只需要關心上述過程中的最後一步。即,將對應的路由交給對應的函數來處理。這一點,在不同的後臺框架的表現形式都是相似的。
雖然表現形式有一些差別,但是總體來說也是差不多的。而對於前端應用來說,也是如此,將對應的 URL 的邏輯交由對應的函數來處理。
使用規則引擎來處理路由與函數的關係。稍有不同的是,後臺的路由完全交由伺服器端來控制,而前端的請求則都是在本地改變其狀態,並且同時在不同的前端框架上,他們在行為上還有一些區別。這取決於我們是否需要後臺渲染,即刷新當前頁面時的表現形式。
數據:獲取與鑒權
實現路由的時候,只是將對應的控制權交給控制器(或稱組件)來處理。而作為一個單頁面應用的控制器,當執行到相應的控制器的時候,就可以根據對應的 blog/12 來獲取到用戶想要的 ID 是 12。這個時候,控制器將需要在頁面上設置一個 loading 的狀態,然後發送一個請求到後臺伺服器。
對於數據獲取來說,我們可以通過axios,我們仍然是寫類似於的形式:
1 axios.get(url) 2 .then(res=>{ 3 console.log(res.data) 4 }) 5 .catch(err=>{ 6 console.log(err); 7 throw err; 8 })
模型麻煩的地方在於:轉變成想要的形式。後臺返回的值是可變的,它有可能不返回,有可能是 null,又或者是與我們要顯示的值不一樣——想要展示的是 54%,而後臺返回的是 0.54。與此同時,我們可能還需要對數值進行簡單的計算,顯示一個範圍、區間,又或者是不同的兩種展示。
同時在必要的時候,我們還需要將這些值存儲在本地,或者記憶體里。當我們重新進入這個頁面的時候,我們再去讀取這些值。
一旦談論到數據的時候,不可避免的我們就需要關心安全因素。對於普通的 Web 應用來說,我們可以做兩件事來保證數據的安全:
- 採用 HTTPS:在傳輸的過程中保證數據是加密的。
- 鑒權:確保指定的用戶只能可以訪問指定的數據。
目前,流行的前端鑒權方式是 Token 的形式,可以是普通的定製 Token,也可以是 JSON Web Token。獲取 Token 的形式,則是通過 Basic 認證——將用戶輸入的用戶名和密碼,經過 BASE64 加密發送給伺服器。伺服器解密後驗證是否是正常的用戶名和密碼,再返回一個帶有時期期限的 Token 給前端。
隨後,當用戶去獲取需要許可權的數據時,需要在 Header 里鑒定這個 Token 是否有限,再返回相應的數據。如果 Token 已經過期了,則返回 401 或者類似的標誌,客戶端就在這個時候清除 Token,並讓用戶重新登錄。
數據展示:模板引擎
現在,我們已經獲取到這些數據了,下一步所需要做的就是顯示這些數據。與其他內容相比,顯示數據就是一件簡單的事,無非就是:
- 依據條件來顯示、隱藏某些數據
- 在模板中對數據進行遍歷顯示
- 在模板中執行方法來獲取相應的值,可以是函數,也可以是過濾器。
- 依據不同的數值來動態獲取樣式
- 等等
不同的框架會存在一些差異。並且現代的前端框架都可以支持單向或者雙向的數據綁定。當相應的數據發生變化時,它就可以自動地顯示在 UI 上。
最後,在相應需要處理的 UI 上,綁上相應的事件來處理。
是在數據顯示的時候,又會涉及到另外一個問題,即組件化。對於一些需要重用的元素,我們會將其抽取為一個通用的組件,以便於我們可以復用它們,並且在這些組件里,也會涉及到相應的參數變化即狀態改變。
交互:事件與狀態管理
完成一步步的渲染之後,我們還需要做的事情是:交互。交互分為兩部分:用戶交互、組件間的交互——共用狀態。
組件交互:狀態管理
用戶從 A 頁面跳轉到 B 頁面的時候,為瞭解耦組件間的關係,我們不會使用組件的參數來傳入值。而是將這些值存儲在記憶體里,在適當的時候調出這些值。當我們處理用戶是否登錄的時候,我們需要一個 isLogined 的方法來獲取用戶的狀態;在用戶登錄的時候,我們還需要一個 setLogin 的方法;用戶登出的時候,我們還需要更新一下用戶的登錄狀態。
在沒有 Redux 之前,我都會寫一個 service 來管理應用的狀態。在這個模塊里寫上些 setter、getter 方法來存儲狀態的值,並根據業務功能寫上一些來操作這個值。然而,使用 service 時,我們很難跟蹤到狀態的變化情況,還需要做一些額外的代碼來特別處理。
有時候也會犯懶一下,直接寫一個全局變數。這個時候維護起代碼來就是一場噩夢,需要全局搜索相應的變數。如果是調用某個特定的 Service 就比較容易找到調用的地方。
用戶交互:事件
事實上,對於用戶交互來說也只是改變狀態的值,即對狀態進行操作。
一個例子,當用戶點擊登錄的時候,發送數據到後臺,由後臺返回這個值。由控制器一一的去修改這些狀態,最後確認這個用戶登錄,併發一個用戶已經登錄的廣播,又或者修改全局的用戶值。
這裡先介紹這麼多。
本文參考文章:
一篇外國文章: HTML,JavaScript和Web的應用程式
作者:明銘之中 HTML中的hash(#號)
作者: mongkey_king SPA
作者:劉貴生 關於Vue項目的seo問題
這裡總結了一下他們的一些文章,方便以後查閱,看他們的文章讓我收穫頗多,一瞬間感慨萬千,技術發展太快,我們只能默默堅持,學習新的技術,爭取自己也有機會做那一頭領頭羊。
如果你看了我的文章感覺學習到了一些知識,那我非常高興。作者水平有限,如有不足之處,還望指正。