新聞中心
開篇
在開始之前我們需要先來搞清楚一個問題:什么是服務(wù)端渲染 ?

米林網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。創(chuàng)新互聯(lián)于2013年創(chuàng)立到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)。
在以往的概念里,渲染的工作更多的是放在客戶端進(jìn)行的,那么為什么現(xiàn)在我們要讓服務(wù)端來做這個工作?
服務(wù)端渲染和客戶端渲染有什么不同之處嗎?
其實(shí)服務(wù)端渲染的工具有很多,看著手冊很快就能上手,并沒有什么難度,關(guān)鍵在于,我們什么場景下需要使用服務(wù)端渲染,什么樣的渲染方案更適合我們的項(xiàng)目;知其然,知其所以然,我們需要先搞清楚服務(wù)端渲染的基本概念和原理,服務(wù)端渲染為什么會出現(xiàn),到底解決了我們的什么問題,掌握整體的渲染邏輯和思路,我們才能在學(xué)習(xí)工具使用時,輕松自在,而即便以后工具有了變化和更新,我們也能得心應(yīng)手,不會再說 “學(xué)不動” 了;
這個邏輯就是所謂的道、法、術(shù)、器的概念;不要僅僅停留在工具的使用和一些工具的奇技淫巧中,更多的要向法、道的層面成長;
什么是 SSR ?
現(xiàn)代化的前端項(xiàng)目,大部分都是單頁應(yīng)用程序,也就是我們說的 SPA ,整個應(yīng)用只有一個頁面,通過組件的方式,展示不同的頁面內(nèi)容,所有的數(shù)據(jù)通過請求服務(wù)器獲取后,在進(jìn)行客戶端的拼裝和展示;這就是目前前端框架的默認(rèn)渲染邏輯,我們稱為:客戶端渲染方案( Client Side Render 簡稱: CSR );
加載渲染過程如下: HTML/CSS 代碼 --> 加載 JavaScript 代碼 --> 執(zhí)行 JavaScript 代碼 --> 渲染頁面數(shù)據(jù)
SPA 應(yīng)用的客戶端渲染方式,最大的問題有兩個方面:
1:白屏?xí)r間過長,用戶體驗(yàn)不好;
2:HTML 中無內(nèi)容,SEO 不友好;
這個問題的原因在于,首次加載時,需要先下載整個 SPA 腳本程序,瀏覽器執(zhí)行代碼邏輯后,才能去獲取頁面真正要展示的數(shù)據(jù),而 SPA 腳本的下載需要較長的等待和執(zhí)行時間,同時,下載到瀏覽器的 SPA 腳本是沒有頁面數(shù)據(jù)的, 瀏覽器實(shí)際并沒有太多的渲染工作,因此用戶看到的是沒有任何內(nèi)容的頁面,不僅如此,因?yàn)轫撁嬷袥]有內(nèi)容,搜索引擎的爬蟲爬到的也是空白的內(nèi)容,也就不利于 SEO 關(guān)鍵字的獲??;
相較于傳統(tǒng)的站點(diǎn),瀏覽器獲取到的頁面都是經(jīng)過服務(wù)器處理的有內(nèi)容的靜態(tài)頁面,有過后端編程經(jīng)驗(yàn)的可能會比較熟悉一些,頁面結(jié)構(gòu)和內(nèi)容,都是通過服務(wù)器處理后,返回給客戶端;
全宇宙首發(fā)動圖,全流程展現(xiàn)
兩相比較我們會發(fā)現(xiàn),傳統(tǒng)站點(diǎn)的頁面數(shù)據(jù)合成在后臺服務(wù)器,而 SPA 應(yīng)用的頁面數(shù)據(jù)合成在瀏覽器,但是無論那種,最終的渲染展示,還是交給瀏覽器完成的,所以,不要誤會,我們這里所說的 服務(wù)端渲染 和 客戶端渲染,指的是頁面結(jié)構(gòu)和數(shù)據(jù)合成的工作,不是瀏覽器展示的工作;
那么能不能借助傳統(tǒng)網(wǎng)站的思路來解決 SPA 的問題又能夠保留SPA的優(yōu)勢呢?不管是白屏?xí)r間長還是 SEO 不友好,實(shí)際都是首屏的頁面結(jié)構(gòu)先回到瀏覽器,然后再獲取數(shù)據(jù)后合成導(dǎo)致的問題,那么,首屏的頁面結(jié)構(gòu)和數(shù)據(jù),只要像傳統(tǒng)站點(diǎn)一樣,先在服務(wù)端合成后再返回,同時將 SPA 腳本的加載依然放到首屏中,此時返回的頁面就是結(jié)構(gòu)和數(shù)據(jù)都有的完整內(nèi)容了,這樣瀏覽器在展示首頁數(shù)據(jù)的同時也能加載 SPA 腳本,搜索引擎的爬蟲同樣也能獲取到對應(yīng)的數(shù)據(jù),解決 SEO 的問題;為了更好的理解這個邏輯,我畫了一個流程圖:
沒錯,這就是我們所說的 服務(wù)端渲染的基本邏輯,服務(wù)端渲染也就是 SSR (Server Side Rendering) ;
白屏?xí)r間過長的問題得以解決,因?yàn)槭状渭虞d時,服務(wù)器會先將渲染好的靜態(tài)頁面返回,在靜態(tài)頁面中再次加載請求 SPA 腳本;
基本原理:首頁內(nèi)容及數(shù)據(jù),在用戶請求之前生成為靜態(tài)頁面,同時加入 SPA 的腳本代碼引入,在瀏覽器渲染完成靜態(tài)頁面后,請求 SPA 腳本應(yīng)用,之后的頁面交互依然是客戶端渲染;
明白了其中的原理,也就是到了道、法的境界,接下來,讓我們下凡進(jìn)入術(shù)、器的應(yīng)用層面感受一下;
其中 Vue 框架和 React 框架都有對應(yīng)的比較成熟的 SSR 解決方案,React對應(yīng)的是 Next.js 框架,Vue 對應(yīng)的就是 Nuxt.js,當(dāng)然,如果你對這些都不感興趣,也可以自己實(shí)現(xiàn)一個 SSR 的服務(wù)端應(yīng)用,我自己之前也寫過一個,如果你感興趣,想看看我實(shí)現(xiàn)的代碼,可以留言給我,回頭做成教程發(fā)出來;
我們以 Vue 對應(yīng)的 Nuxt.js 為例,來具體感受服務(wù)端渲染;
Nuxt.js 應(yīng)用
Nuxt.js 是一個基于 Vue.js 的通用應(yīng)用框架。Nuxt.js 預(yù)設(shè)了利用 Vue.js 開發(fā)服務(wù)端渲染的應(yīng)用所需要的各種配置,為基于 Vue.js 的應(yīng)用提供生成對應(yīng)的靜態(tài)站點(diǎn)的功能。打開 Nuxt.js官網(wǎng):https://www.nuxtjs.cn/ ,學(xué)習(xí)指南寫的非常詳細(xì)且通俗易懂,根據(jù)指南,我們可以看到有兩種安裝方式,一種使用 create-nuxt-app 腳手架工具,另一種是自己手動創(chuàng)建;
安裝
腳手架安裝
接下來我們分別嘗試不同的安裝方式,先使用腳手架進(jìn)行安裝,執(zhí)行命令 : npx create-nuxt-app creact-nuxt
接著,在命令行中會有很多的選擇項(xiàng),分別有項(xiàng)目名稱、開發(fā)語言、UI組件庫、服務(wù)器框架、測試框架、HTTP請求庫等等,可以根據(jù)自己的需要進(jìn)行不同的選擇,安裝成功過后,命令行中會給出對應(yīng)的提示信息。
我們可以根據(jù)提示信息,運(yùn)行項(xiàng)目,項(xiàng)目有開發(fā)環(huán)境和生產(chǎn)環(huán)境兩種運(yùn)行方式,開發(fā)環(huán)境下直接使用 npm run dev 即可,而要運(yùn)行生產(chǎn)環(huán)境,則需要先進(jìn)行 build 編譯,編譯成功后才能開啟項(xiàng)目運(yùn)行;
因?yàn)轫?xiàng)目是剛剛初始化的,我們并沒有寫任何內(nèi)容,所以,不管使用那種運(yùn)行方式,我們能看到的都是下面這個頁面內(nèi)容;
手動安裝
不同于腳手架安裝,手動安裝需要我們自己創(chuàng)建項(xiàng)目并安裝所需擴(kuò)展和插件,還需要我們自己寫好組件代碼,然后配置執(zhí)行命令,才能啟動運(yùn)行,但是,手動創(chuàng)建更加考驗(yàn)大家對項(xiàng)目的整體把控能力;
執(zhí)行命令: mkdir nuxtnpm 創(chuàng)建文件夾后,切換目錄:cd nuxtnpm ;
然后執(zhí)行命令:npm init -y 創(chuàng)建項(xiàng)目并生成 package.json 文件;
使用命令:npm install nuxt --save 安裝 Nuxt.js 框架;
在 nuxtnpm 目錄中,創(chuàng)建 pages 目錄及 pages/index.vue 組件文件,在組件文件中,寫如下代碼,打聲招呼:
-
-
嗨 Nuxt.js
-
最后,我們還要在 package.json 文件中,配置運(yùn)行命令的腳本參數(shù):
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1",
- "dev": "nuxt",
- "build": "nuxt build",
- "start": "nuxt start",
- "generate": "nuxt generate"
- },
配置好命令參數(shù)后,就和前面的運(yùn)行套路是一樣的了:
npm run dev 啟動一個熱加載的 Web 服務(wù)器(開發(fā)模式)
npm run build 編譯項(xiàng)目,利用 webpack 編譯應(yīng)用,壓縮 JS 和 CSS 資源(發(fā)布用);
npm run start 以生產(chǎn)模式啟動一個 Web 服務(wù)器 (需要先進(jìn)行項(xiàng)目編譯)。
項(xiàng)目運(yùn)行后,我們就可以看到剛剛寫的組件內(nèi)容了;
需要注意的是,pages 目錄是必須的,Nuxt.js 框架會自動讀取該目錄下所有的 .vue 文件并自動生成對應(yīng)的路由配置。
路由
基礎(chǔ)路由
基礎(chǔ)路由不需要配置,Nuxt.js 會根據(jù) pages 中的文件夾及文件,自動生成的路由配置
假設(shè) pages 的目錄結(jié)構(gòu)如下:
- pages/
- --| user/
- -----| index.vue
- -----| one.vue
- --| index.vue
那么,Nuxt.js 自動生成的路由配置如下:
- router: {
- routes: [
- {
- name: 'index',
- path: '/',
- component: 'pages/index.vue'
- },
- {
- name: 'user',
- path: '/user',
- component: 'pages/user/index.vue'
- },
- {
- name: 'user-one',
- path: '/user/one',
- component: 'pages/user/one.vue'
- }
- ]
- }
同樣的,在 /.nuxt/router.js 文件中,我們也能夠看到相關(guān)內(nèi)容;
路由導(dǎo)航
Nuxt 中的路由導(dǎo)航有三種方式,一種就是普通的 a 標(biāo)簽跳轉(zhuǎn),太過于基礎(chǔ)這里就不說了,兩外兩種分別是 nuxt-link 組件和編程式導(dǎo)航,nuxt-link 組件用于在頁面中添加鏈接跳轉(zhuǎn)到其他頁面,目前
而編程式導(dǎo)航的用法,同樣與 Vue 中的使用方式一致:
-
-
nuxt-link 跳轉(zhuǎn):
-
Go to user
-
編程式導(dǎo)航 跳轉(zhuǎn):
-
-
動態(tài)路由
在 Nuxt.js 里面定義帶參數(shù)的動態(tài)路由,需要創(chuàng)建對應(yīng)的 以下劃線作為前綴 的 Vue 文件 或 目錄。
下劃線后面的名字隨意命名,但是在獲取動態(tài)路由參數(shù)時,文件的名字就是獲取的關(guān)鍵字,用法與 Vue-Router 基本一致:
\pages\user_kk.vue
-
-
動態(tài)路由-route
-
-
獲取參數(shù),打印: {{$route.params.kk}}
-
控制臺也有輸出
-
- .mis{
- background: coral;
- }
訪問:
http://localhost:3000/user/3
在 Nuxt.js 執(zhí)行 generate 命令時,動態(tài)路由會被忽略,(后面重點(diǎn)講)
嵌套路由
你可以通過 vue-router 的子路由創(chuàng)建 Nuxt.js 應(yīng)用的嵌套路由。創(chuàng)建內(nèi)嵌子路由,需要添加一個 Vue 文件,同時添加一個與該文件同名的目錄用來存放子視圖組件。在父組件(.vue文件) 內(nèi)增加
父組件文件內(nèi)容
\pages\order.vue
-
-
嵌套路由
-
-
-
嵌套子組件文件及內(nèi)容
\pages\order\index.vue 嵌套組件默認(rèn)顯示,訪問路徑:
http://localhost:3000/order
-
-
嵌套子路由 - index
-
-
-
-
\pages\order\info.vue 訪問路徑: http://localhost:3000/order/info
-
- order->info
-
\pages\order\list.vue 訪問路徑: http://localhost:3000/order/list
-
-
order-> list
-
{{dataObj[0].name}}
-
異步數(shù)據(jù)-asyncData
Nuxt.js 擴(kuò)展了 Vue.js,增加了一個叫 asyncData 的方法,使得我們可以在設(shè)置組件的數(shù)據(jù)之前能異步獲取或處理數(shù)據(jù)。asyncData 方法會在組件(限于頁面組件)每次加載之前被調(diào)用。它可以在服務(wù)端或路由更新之前被調(diào)用。Nuxt.js 會將 asyncData 返回的數(shù)據(jù)融合組件 data 方法返回的數(shù)據(jù)一并返回給當(dāng)前組件。
-
- user-index page
-
-
-
-
{{ v.name }}
-
-
-
-
-
Nuxt.js 對 SSG 的支持
在開始之前,我們需要先了解 SSG 的含義,SSG(Static Site Generators):靜態(tài)站點(diǎn)生成。
就是將應(yīng)用中用到的所有頁面,全部生成靜態(tài)文件的方案;靜態(tài)站點(diǎn)生成方案,更適合 CDN、緩存、內(nèi)容數(shù)據(jù)無變化的頁面,比如:宣傳頁、博客文章、幫助文檔、新聞頁面、電商產(chǎn)品列表等眾多應(yīng)用場景;因?yàn)轫撁娑际鞘孪壬珊玫模淮螛?gòu)建,反復(fù)使用,訪問速度快。
那么,在 Nuxt.js 中如何將應(yīng)用靜態(tài)化導(dǎo)出呢?npm run generate 命令就是用來專門做靜態(tài)導(dǎo)出的,這個命令執(zhí)行后,Nuxt 會根據(jù)路由配置,將應(yīng)用的全部內(nèi)容生成對應(yīng)的 HTML 靜態(tài)站點(diǎn)資源,這個命令會創(chuàng)建一個 dist 文件夾,所有靜態(tài)化后的資源文件均在其中。
前面說 在 Nuxt.js 執(zhí)行 generate 命令時,動態(tài)路由會被忽略。
動態(tài)路由手動配置
如果想讓 Nuxt.js 為動態(tài)路由也生成靜態(tài)文件,需要指定動態(tài)路由參數(shù)的值,并配置到 routes 數(shù)組中去。
我們可以在 nuxt.config.js 中為 /users/:id 路由配置如下:
- module.exports = {
- generate: {
- routes: ['/users/1', '/users/2', '/users/3']
- }
- }
動態(tài)路由數(shù)據(jù)生成
但是如果路由動態(tài)參數(shù)的值是動態(tài)的而不是固定的,應(yīng)該怎么做呢?
可以使用一個返回 Promise 對象類型的 函數(shù),意思就是,發(fā)送請求獲取所有數(shù)據(jù),根據(jù)返回的數(shù)據(jù),生成所有可能的路由,再根據(jù)所有路由,生成全部的靜態(tài)文件
nuxt.config.js
- const axios = require('axios')
-
- module.exports = {
- generate: {
- // 生成路由文件,而不是目錄
- subFolders:false,
- routes() {
- // 請求數(shù)據(jù)
- return axios.get('http://127.0.0.1:80/three').then(res => {
- const resData = JSON.parse(res.data);
- return resData.map(user => {
- // 拼裝路由
- return '/user/' + user.id
- })
- })
- }
- }
- }
異步數(shù)據(jù)-asyncData 與 mounted 的區(qū)別
mounted 在靜態(tài)站點(diǎn)生成時,不會執(zhí)行獲取數(shù)據(jù),代碼會被編譯進(jìn)靜態(tài)生成的 JS 中,瀏覽器渲染時才會被執(zhí)行,
asyncData 在導(dǎo)出靜態(tài)站點(diǎn)時,會執(zhí)行代碼,并將數(shù)據(jù)直接編譯進(jìn) HTML 中,代碼不會編譯到靜態(tài)文件的 JS 中;
【責(zé)任編輯: 龐桂玉 TEL:(010)68476606】
當(dāng)前名稱:Vue服務(wù)端渲染原理及入門
網(wǎng)頁路徑:http://www.5511xx.com/article/cdshpco.html


咨詢
建站咨詢
