詳解服務(wù)端預(yù)渲染之Nuxt(介紹篇)
現(xiàn)在前端開發(fā)一般都是前后端分離,mvvm和mvc的開發(fā)框架,如Angular、React和Vue等,雖然寫框架能夠使我們快速的完成開發(fā),但是由于前后臺(tái)分離,給項(xiàng)目SEO帶來很大的不便,搜索引擎在檢索的時(shí)候是在網(wǎng)頁中爬取數(shù)據(jù),由于單頁面應(yīng)用讀取到的頁面是幾乎空白的,無法爬取到任何數(shù)據(jù)信息。
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<meta name=viewport content="width=device-width,initial-scale=1">
<title>authorization_web</title>
</head>
<body>
<div id=app></div>
</body>
</html>
如上代碼,單頁面應(yīng)用查看源代碼的時(shí)候如上所示,所以搜索引擎無法爬取到任何信息,搜索引擎會(huì)認(rèn)為當(dāng)前頁面為一個(gè)空頁面。為了解決SEO問題,推出了SSR服務(wù)端預(yù)渲染,以便提高對(duì)SEO優(yōu)化。
什么是SSR
在認(rèn)識(shí)SSR之前,首先對(duì)CSR與SSR之間做個(gè)對(duì)比。
首先看一下傳統(tǒng)的web開發(fā),傳統(tǒng)的web開發(fā)是,客戶端向服務(wù)端發(fā)送請(qǐng)求,服務(wù)端查詢數(shù)據(jù)庫,拼接HTML字符串(模板),通過一系列的數(shù)據(jù)處理之后,把整理好的HTML返回給客戶端,瀏覽器相當(dāng)于打開了一個(gè)頁面。這種比如我們經(jīng)常聽說過的jsp,PHP,aspx也就是傳統(tǒng)的MVC的開發(fā)。
SPA應(yīng)用,到了Vue、React,單頁面應(yīng)用優(yōu)秀的用戶體驗(yàn),逐漸成為了主流,頁面整體式j(luò)avaScript渲染出來的,稱之為客戶端渲染CSR。SPA渲染過程。由客戶端訪問URL發(fā)送請(qǐng)求到服務(wù)端,返回HTML結(jié)構(gòu)(但是SPA的返回的HTML結(jié)構(gòu)是非常的小的,只有一個(gè)基本的結(jié)構(gòu),如第一段代碼所示)??蛻舳私邮盏椒祷亟Y(jié)果之后,在客戶端開始渲染HTML,渲染時(shí)執(zhí)行對(duì)應(yīng)javaScript,最后渲染template,渲染完成之后,再次向服務(wù)端發(fā)送數(shù)據(jù)請(qǐng)求,注意這里時(shí)數(shù)據(jù)請(qǐng)求,服務(wù)端返回json格式數(shù)據(jù)??蛻舳私邮諗?shù)據(jù),然后完成最終渲染。
SPA雖然給服務(wù)器減輕了壓力,但是也是有缺點(diǎn)的:
- 首屏渲染時(shí)間比較長:必須等待JavaScript加載完畢,并且執(zhí)行完畢,才能渲染出首屏。
- SEO不友好:爬蟲只能拿到一個(gè)div元素,認(rèn)為頁面是空的,不利于SEO。
為了解決如上兩個(gè)問題,出現(xiàn)了SSR解決方案,后端渲染出首屏的DOM結(jié)構(gòu)返回,前端拿到內(nèi)容帶上首屏,后續(xù)的頁面操作,再用單頁面路由和渲染,稱之為服務(wù)端渲染(SSR)。
SSR渲染流程是這樣的,客戶端發(fā)送URL請(qǐng)求到服務(wù)端,服務(wù)端讀取對(duì)應(yīng)的url的模板信息,在服務(wù)端做出html和數(shù)據(jù)的渲染,渲染完成之后返回html結(jié)構(gòu),客戶端這時(shí)拿到的之后首屏頁面的html結(jié)構(gòu)。所以用戶在瀏覽首屏的時(shí)候速度會(huì)很快,因?yàn)榭蛻舳瞬恍枰俅伟l(fā)送ajax請(qǐng)求。并不是做了SSR我們的頁面就不屬于SPA應(yīng)用了,它仍然是一個(gè)獨(dú)立的spa應(yīng)用。
SSR是處于CSR與SPA應(yīng)用之間的一個(gè)折中的方案,在渲染首屏的時(shí)候在服務(wù)端做出了渲染,注意僅僅是首屏,其他頁面還是需要在客戶端渲染的,在服務(wù)端接收到請(qǐng)求之后并且渲染出首屏頁面,會(huì)攜帶著剩余的路由信息預(yù)留給客戶端去渲染其他路由的頁面。
Nuxt.js 介紹
在Nuxt官方網(wǎng)站有一句這樣的話:Nuxt.js預(yù)設(shè)了使您開發(fā)Vue.js應(yīng)用程序所需的所有配置。Nuxt是一個(gè)基于Vue.js的通用應(yīng)用框架。通過對(duì)客戶端/服務(wù)端基礎(chǔ)框架的抽象組織,Nuxt主要關(guān)注的是應(yīng)用的ui渲染。
通過上面的這些介紹可以簡單的得出:
- Nuxt不僅僅用于服務(wù)端渲染也可以用于SPA應(yīng)用的開發(fā)
- 利用Nuxt提供的項(xiàng)目結(jié)構(gòu)、異步數(shù)據(jù)加載,中間件的支持,布局等特性可大幅提升開發(fā)效率
- Nuxt可用于網(wǎng)站靜態(tài)化,可以使用命令將整個(gè)網(wǎng)頁打包成靜態(tài)頁面,使SEO更加友好
Nuxt.js 特性
- 基于Vue
- 自動(dòng)代碼分層
- 服務(wù)端渲染
- 強(qiáng)大的路由功能,支持異步數(shù)據(jù)
- 靜態(tài)文件服務(wù)
- EcmaScript6和EcmaScript7的語法支持
- 打包和壓縮JavaScript和Css
- HTML頭部標(biāo)簽管理
- 本地開發(fā)支持熱加載
- 集成ESLint
- 支持各種樣式預(yù)編譯器SASS、LESS等等
- 支持HTTP/2推送
Nuxt 渲染流程
一個(gè)完整的服務(wù)器請(qǐng)求到渲染的流程

通過上面的流程圖可以看出,當(dāng)一個(gè)客戶端請(qǐng)求進(jìn)入的時(shí)候,服務(wù)端有通過nuxtServerInit這個(gè)命令執(zhí)行在Store的action中,在這里接收到客戶端請(qǐng)求的時(shí)候,可以將一些客戶端信息存儲(chǔ)到Store中,也就是說可以把在服務(wù)端存儲(chǔ)的一些客戶端的一些登錄信息存儲(chǔ)到Store中。之后使用了中間件機(jī)制,中間件其實(shí)就是一個(gè)函數(shù),會(huì)在每個(gè)路由執(zhí)行之前去執(zhí)行,在這里可以做很多事情,或者說可以理解為是路由器的攔截器的作用。然后再validate執(zhí)行的時(shí)候?qū)蛻舳藬y帶的參數(shù)進(jìn)行校驗(yàn),在asyncData與fetch進(jìn)入正式的渲染周期,asyncData向服務(wù)端獲取數(shù)據(jù),把請(qǐng)求到的數(shù)據(jù)合并到Vue中的data中,
Nuxt說明
Nuxt安裝:
確保安裝了npx(npx在NPM版本5.2.0默認(rèn)安裝了):
npx create-nuxt-app <項(xiàng)目名>
安裝向?qū)В?/p>
Project name // 項(xiàng)目名稱 Project description // 項(xiàng)目描述 Use a custom server framework // 選擇服務(wù)器框架 Choose features to install // 選擇安裝的特性 Use a custom UI framework // 選擇UI框架 Use a custom test framework // 測試框架 Choose rendering mode // 渲染模式 Universal // 渲染所有連接頁面 Single Page App // 只渲染當(dāng)前頁面
這些都是比較重要的其他的配置內(nèi)容就不做介紹了,一路回車即可。
目錄結(jié)構(gòu)介紹
assets // 存放素材(需要執(zhí)行webpack預(yù)處理操作) components // 組件 layouts // 布局文件 static // 靜態(tài)文件(不需要webpack預(yù)處理操作) middleware // 中間件 pages // 所有頁面 plugins // 插件 server // 服務(wù)端代碼 store // vuex
配置文件
const pkg = require('./package')
module.exports = {
mode: 'universal', // 當(dāng)前渲染使用模式
head: { // 頁面head配置信息
title: pkg.name, // title
meta: [ // meat
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: pkg.description }
],
link: [ // favicon,若引用css不會(huì)進(jìn)行打包處理
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
},
loading: { color: '#fff' }, // 頁面進(jìn)度條
css: [ // 全局css(會(huì)進(jìn)行webpack打包處理)
'element-ui/lib/theme-chalk/index.css'
],
plugins: [ // 插件
'@/plugins/element-ui'
],
modules: [ // 模塊
'@nuxtjs/axios',
],
axios: {},
build: { // 打包
transpile: [/^element-ui/],
extend(config, ctx) { // webpack自定義配置
}
}
}
Nuxt運(yùn)行命令
{
"scripts": {
// 開發(fā)環(huán)境
"dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
// 打包
"build": "nuxt build",
// 在服務(wù)端運(yùn)行
"start": "cross-env NODE_ENV=production node server/index.js",
// 生成靜態(tài)頁面
"generate": "nuxt generate"
}
}
結(jié)語
這里簡單的對(duì)Nuxt做了一些介紹,會(huì)持續(xù)更新對(duì)Nuxt的跟進(jìn),希望會(huì)對(duì)大家有所幫助,如果有什么問題,可以在下面留言。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
WebStorm啟動(dòng)vue項(xiàng)目報(bào)錯(cuò)代碼:1080?throw?err解決辦法
在使用webstorm新建vue項(xiàng)目時(shí)常會(huì)遇到一些報(bào)錯(cuò),下面這篇文章主要給大家介紹了關(guān)于WebStorm啟動(dòng)vue項(xiàng)目報(bào)錯(cuò)代碼:1080?throw?err的解決辦法,文中將解決辦法介紹的非常詳細(xì),需要的朋友可以參考下2023-12-12
Vue2和Vue3的nextTick實(shí)現(xiàn)原理
Vue 中的數(shù)據(jù)綁定和模板渲染都是異步的,那么如何在更新完成后執(zhí)行回調(diào)函數(shù)呢?這就需要用到 Vue 的 nextTick 方法了,本文詳細(xì)介紹了Vue2和Vue3的nextTick實(shí)現(xiàn)原理,感興趣的同學(xué)可以參考一下2023-04-04
分享一個(gè)精簡的vue.js 圖片lazyload插件實(shí)例
本篇文章主要介紹了分享一個(gè)精簡的vue.js 圖片lazyload插件實(shí)例。非常具有實(shí)用價(jià)值,需要的朋友可以參考下。2017-03-03
利用Vue3的Teleport實(shí)現(xiàn)模態(tài)對(duì)話框功能
在前端開發(fā)中,模態(tài)對(duì)話框是一種常見的用戶交互方式,它能夠有效地提示用戶、收集信息或確認(rèn)操作,隨著現(xiàn)代框架的演進(jìn),Vue 3 的出現(xiàn)為我們提供了更便捷、高效的方式來處理復(fù)雜的界面布局,今天,我們將深入探討如何利用 Vue 3 的新特性 Teleport 來實(shí)現(xiàn)模態(tài)對(duì)話框2025-02-02
使用vue自定義如何實(shí)現(xiàn)Tree組件和拖拽功能
這篇文章主要介紹了使用vue自定義如何實(shí)現(xiàn)Tree組件和拖拽功能,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12
vue報(bào)錯(cuò)Cannot?read?properties?of?undefined?(...)類型的解決辦法
這篇文章主要給大家介紹了關(guān)于vue報(bào)錯(cuò)Cannot?read?properties?of?undefined?(...)類型的解決辦法,文中通過代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-04-04

