一個小時搭建一個全棧 Web 應用框架(下)——美化與功能

發表於2017-09-05

如果你遵循前面的教程中的步驟,現在應該有了一個可以工作的全棧Web應用程式框架。

點選直達前文 >> 【譯】一個小時搭建一個全棧Web應用框架(上)

如果沒有,但還是要繼續學習本教程,可以到我的GitHub頁面下載程式碼

對於下一個魔術,我們將把一個顯示“Hello World!”的簡單靜態頁面轉換成一個漂亮的單頁面WEB應用。 這個頁面能夠與後端通訊,並且在收到新資訊時立即更新,而無需使用者重新整理頁面。我們即將建立的頁面,在每次點選按鈕時,會以隨機的歐洲語言返回“Hello”。

這是我們的頁面:

2372598012-59a77c7d2a7de_articlex

為了能夠實現這一點,我們需要先弄清楚以下的問題:

  1. 每次呼叫 /hello 端點時,如何返回一個隨機的歐洲語言“Hello”。
  2. 如何從伺服器請求資訊。
  3. 如何將返回的資訊無縫顯示給使用者,從而無需重新整理頁面。
  4. 如何在頁面上新增樣式,可以在頁面上建立一個大的居中的按鈕並新增文字。
  5. 最後,我們必須搞清楚應該如何新增一個背景影像。

從伺服器返回隨機語言的“Hello”

每當我們與伺服器上的 /hello 端點進行通話時,為了能夠請求一個隨機的歐洲語言“Hello”,必須更改 server/server.py 檔案中的功能。每次呼叫它時,都不會返回靜態的“Hello World”,而是從“Hello”列表中選擇一個隨機語言的“Hello”。為了實現這個功能,需要進行以下更改:

這個函式定義了一個歐洲語言的“hello”列表, 然後我們呼叫這個函式時,使用 random.choice()從列表中隨機選擇一個專案。

修改 hello() 函式,以便在每次呼叫它時返回get_hello()

修改 /hello 以返回我們感興趣的資訊,我們現在需要弄清楚如何從前端得到這些資訊。

元件化的重要性 – 在 React 中建立一個Hello類

把問題分解被認為是良好的程式設計習慣。 只要有可能,你應該儘量使自己的函式只做一件事情,並且做好。這點同樣適用於類。你可以考慮將每個函式或類都作為單獨的元件。

React是為元件化而設計的。這意味著它是用多個較小的部分來構建你的網站的。就像玩樂高一樣,可以輕鬆地將一個元件替換成另外一個,也可以複用元件,這也能幫助其他開發人員瞭解你的程式碼。我們應該努力的編寫可理解的程式碼,因為這樣可以使我們的程式更容易維護和擴充套件。

考慮到元件化,我們建立一個 Hello 類來處理我們網頁上的問候語。該類將從伺服器上的 /hello 端點點獲取一個 “Hello” ,並將其顯示給使用者。 它也應該有一個“name”引數,這樣就可以向某個具體的人進行問候。

通過更改 React App 類中的render函式,使其呼叫Hello類,我們就可以很快的完成功能,而不是使用舊的程式碼。傳遞名稱“Rimini”作為引數。出於結構化的目的,我們將把Hello類放在一個 PageHeader 中。

建立Hello類

前面我們修改了 App 類使其能夠呼叫 hello 類, 接下來需要建立 Hello 類。在 js/ 目錄下建立一個名為 hello.jsx 的檔案, 在此檔案中定義一個名為 hello 的類。

元件與道具

在這一點上,你可能對建構函式中發生了什麼有很多疑問。

在 React 中有一種叫做元件和道具的東西。 Props是建立時傳遞給建構函式的不可變引數。 道具是公開的,修改他們將違反 React 的基本使用原則。狀態是內部的,可變的。每次更新狀態時,都會在UI中重新展現。如果希望更深入地瞭解其運作方式,我強烈建議你閱讀React文件中有關生命週期和狀態的部分。

我們將在Hello類中新增一個名為personaliseGreeting() 的函式。 當我們點選按鈕獲得一個新的問候語時,它將會處理網頁上的問候語的更新操作。 請注意,我們使用this.setState()與名為“greeting”的key。你必須使用這個語法才能讓 React 自動重新整理網頁上的“greeting”狀態。

渲染問候語

為了讓問候語出現在頁面上,必須在render函式中呼叫“{this.state.greeting}”。我們還必須新增一個帶有回撥函式的按鈕,這個函式叫做getPythonHello(),我們很快就會實現它。這個函式在呼叫使用Python編寫的後端時,將會得到一個新的“Hello”。

請注意,我已經將標題和按鈕HTML內嵌到了我的程式碼中,所以可以很輕鬆地控制他們在頁面上的最終位置。

繫結“this”

因為JavaScript中的類方法沒有做預設繫結,所以當我們想在函式回撥中使用“this”時,就必須在建構函式中建立一個繫結。否則“this”將會是 undefined 的。 這適用於在 JavaScript 中呼叫without() 的情況。一個典型的例子就是 render() 中的 “onClick = {this.getPythonHello}”

從伺服器請求資訊

React 沒有提供執行HTTP請求的內建方式。為了能夠從伺服器請求資訊,我們將不得不找一個可以做這件事的庫。 一個最簡單的方法就是引入 jQuery 庫。jQuery 是一個 javascript 庫,通過在$符號後面提供縮寫函式來簡化標準的 JavaScript 功能。

首先安裝jQuery依賴關係:

將 jQuery 依賴新增到要使用的 React 檔案中,也就是 Hello.jsx 中。應該將此依賴新增到 Hello 類的定義前面。

將查詢依賴新增到React檔案中意味著可以在自己的React程式碼中使用標準的 jQuery 函式,只要它們以我們剛剛定義的“$”變數開始。下面讓我們用它來從伺服器獲取一個“Hello”。

我們將使用 HTTP 協議的 GET 請求獲取資訊。GET 實質上是HTTP請求的“只讀”模式。可以用來獲取資訊,但是不能要求伺服器更改它。

在 hello.jsx 檔案中的Hello類中新增以下函式:

此函式通過jQuery 的 GET請求,連線 /hello 端點。然後得到從伺服器返回的一個歐洲語言的“hello”資訊,再它列印到瀏覽器的開發控制檯,最後將它傳遞給Hello類中的另一個函式,呼叫 personaliseGreeting()

當 rebuild 前端程式碼(npm run watch),並重新啟動 python 伺服器後。 應該能看到以下內容:

2372598012-59a77c7d2a7de_articlex

 

有一行問候語,一個按鈕,點選按鈕可以更改問候語。 這個頁面看起來很不錯,因為我們在index.html中包含了Bootstrap樣式。

使用CSS樣式美化頁面

我們終於有了一個能夠與使用者互動的產品。如果我們願意,就可以到此為止了,並對自己說:我對這些成就感到滿意。不過就我個人而言,我更喜歡在我的Web應用中新增一些設計元素,讓他們變得更加漂亮。所以,我們將用CSS使標題能夠覆蓋整個螢幕,而不是在頁面的頂部。CSS是為HTML設計的一種樣式語言,它的作用相當於在Word文件中更改字型大小,樣式和位置。

使 Webpack 能夠處理 CSS

為了能夠在我們的WEB應用中使用CSS,必須安裝一些載入器和外掛,並將它們新增到Webpack配置檔案中。這是因為 Webpack 預設只能處理JavaScript。

安裝下列外掛:

  • css-loader
  • style-loader
  • extract-text-webpack-plugin

css-loader 和 style-loader 能夠使 Webpack 處理 CSS。 通過新增這些載入器,Webpack 將能夠將我們需要的任何 CSS 繫結到 bundle.js 中。 不過在這裡存在一個問題,JavaScript 和 CSS 將不會在你的頁面上單獨進行載入,這可能導致 UI 元件在 JavaScript 載入之前無法顯示。這點很差勁,因為在糟糕的網路上,我們辛辛苦苦設計出來的頁面可能會載入的非常緩慢。

不過可以通過新增 extract-text-webpack-plugin 來解決這個問題。 這個外掛能夠將 CSS 分解成一個單獨的包,我們可以把它附加到 HTML 上。 這樣就可以使 CSS 再次獨立於 JavaScript 進行載入。

在你的webpack.config.js檔案的 modules.rules 部分新增下面的CSS規則:

將ExtractTextPlugin外掛新增到 webpack.config.js如果您感到困惑,請檢視我的 webpack 檔案)。注意,在建立時,需要將捆綁的CSS檔名傳給此外掛。我們將呼叫檔案’styles.css’。

最後,我們需要將 styles.css 包新增到index.html中,以確保樣式被載入。將以下行新增到你的index.html檔案中的 head 部分(可以參考我的程式碼):

新增CSS規則

現在可以確保我們的設定可以正確處理CSS了,我們將在css資料夾中建立一個名為fullstack.css 的檔案。我已經新增了幾個不同的規則,以確保文字和按鈕出現在正確的位置,並且文字是大號的細體。

這是我的 fullstack.css 檔案中的一個規則。 它使 “Hello Rimini” 文字變得越來越細:

在建立 fullstack.css 檔案之後,我們需要將它新增到使用規則的 React 元件中,這樣它們才能生效。由於標題在 App.jsx 中定義,所以需要新增以下程式碼:

fullstack.css 檔案中的標題樣式現在將由 Webpack 拾取,並繫結到 styles.css 檔案中。當我們重新整理頁面時,應該如下圖所示。注意,如果你用的瀏覽器不是 Chrome 的話,字型可能和圖中不一樣:

2372598012-59a77c7d2a7de_articlex

 

被CSS裝飾後的頁面

完成 – 新增背景圖

Webpack 本身並不理解影像的概念。因此,我們還需要新增一個可以在Web應用程式中使用它們的載入程式。我們需要安裝名為“file-loader”的loader。

安裝 file-loader:

將file-loader規則新增到 webpack.config.js 檔案中的modules.rules部分:

將要使用的影像新增到images/ folder。將其命名為“header.jpg”。

為了能夠使影像成為網頁頭部的背景,我們需要將其作為背景影像新增到 fullstack.css 檔案的頁首部分。

接下來要做的是把影像載入到使用它的 React 檔案中。如果沒有在 React 中顯式載入圖片,Webpack 將不會棒的它,也不會把它顯示在頁面上。這種行為不是很直觀,在我第一次在自己的應用中新增一個背景影像時,曾經犯過這個錯誤。

在App.jsx中進行如下更改:

將此函式新增到你的App類:

這個函式建立了一個新的Image物件,並將源設定為你的標題圖片。

我們需要做的最後一件事是,確保在渲染頁面時載入影像。 這意味著我們必須在render()函式中呼叫 addHeaderImg()函式。

將下列程式碼新增到render()函式中:

重新整理瀏覽器視窗時,應該看到以下內容:

2372598012-59a77c7d2a7de_articlex

恭喜你!你已成功建立了一個全棧 Web 應用程式!

相關文章