想要學(xué)習(xí)nuxt.js颗圣,首先要弄清楚客戶端渲染和服務(wù)端渲染這兩個概念。
一屁使、客戶端渲染 VS 服務(wù)端渲染
1. 客戶端渲染
簡單理解就是在岂,在服務(wù)端放一個html 頁面,客戶端發(fā)起請求時蛮寂,服務(wù)端把頁面(響應(yīng)的是字符串)發(fā)送過去洁段。客戶端從上到下依次解析共郭,如果發(fā)現(xiàn)ajax請求就再發(fā)送新請求祠丝,拿到ajax 響應(yīng)結(jié)果以后渲染模板引擎。整個過程至少要發(fā)起兩次請求除嘹。如圖:
但是写半,這種渲染方式存在的弊端也日益顯露出來,比如首屏渲染慢尉咕,不利于seo等問題叠蝇。想對應(yīng)的,服務(wù)端渲染恰好彌補(bǔ)了這些不足年缎。
2. 服務(wù)端渲染:
也稱SSR悔捶,即server side render的縮寫。在服務(wù)端渲染出完整的首屏dom結(jié)構(gòu)单芜,直接發(fā)送到瀏覽器蜕该;前端拿到的內(nèi)容包括首屏及完整spa結(jié)構(gòu),應(yīng)用激活后依然按照spa方式運(yùn)行洲鸠。整個過程只向服務(wù)端發(fā)起一次請求堂淡。如圖:
服務(wù)端渲染有兩大優(yōu)點(diǎn):
一是更利于SEO馋缅。因?yàn)榕老x只會爬取源碼,不會執(zhí)行腳本绢淀。使用了MVVM框架之后萤悴,頁面的大多數(shù)DOM元素是在客戶端根據(jù)js動態(tài)生成的,可供爬蟲抓取分析的內(nèi)容很少皆的。而且瀏覽器爬蟲不會等數(shù)據(jù)加載完成之后再去抓取覆履。服務(wù)端渲染返回的是已經(jīng)獲取了異步數(shù)據(jù)并執(zhí)行JavaScript腳本的最終HTML,爬蟲就可以抓取完整的頁面信息费薄。
二是更利于首屏渲染内狗。對服務(wù)端渲染而言,首屏渲染是node發(fā)送過來的html字符串义锥,不依賴于js文件柳沙,這樣用戶就能更快地看到頁面內(nèi)容。尤其是大型單頁應(yīng)用拌倍,資源請求量大赂鲤,造成首屏渲染加載緩慢,使用服務(wù)端渲染就可以在很大程度上解決首頁的白屏等待問題柱恤。
Nuxt.js作為Vue.js的通用框架数初,就常被用來作SSR。
二梗顺、nuxt.js
nuxt是一個專注于ui渲染的應(yīng)用框架泡孩,可以快速搭建項(xiàng)目,還提供了服務(wù)端渲染的功能寺谤。
1. 安裝
直接用vue-cli安裝
vue init nuxt-community/starter-template <project-name>
2. nuxt推薦的項(xiàng)目結(jié)構(gòu)
assets——資源文件
components——組件
layouts——布局仑鸥,默認(rèn)default。所有頁面都會加載在布局頁面中的<nuxt />標(biāo)簽中变屁。如果要在普通頁面中使用下級路由眼俊,則要在頁面中添加<nuxt-child />
middleware——中間件:每個頁面加載前調(diào)用,在頁面中調(diào)用的方法是middleware: 'middlewareName'粟关。
node_modules——依賴包
nuxt.config.js——個性化配置
package.json——
pages——頁面疮胖。根頁面是index.vue,二級頁面只要添加文件夾闷板。動態(tài)路由頁面的名稱格式是:_變量.vue
plugins——插件
static——靜態(tài)文件(不需要webpack打包的)澎灸。
store——狀態(tài)管理
yarn.lock
3. 生命周期
Nuxt在vue的基礎(chǔ)上對生命周期做了擴(kuò)展:
export defualt {
middleware(){ }, // 服務(wù)端
validate(){ }, // 服務(wù)端
asyncData(){ }, // 服務(wù)端
fetch(){ }, // store數(shù)據(jù)加載
beforeCreate(){ }, // 服務(wù)端和客戶端都會執(zhí)行
created(){ }, // 服務(wù)端和客戶端都會執(zhí)行
beforeMount(){ }, //
mounted(){ } // 客戶端
}
4. asyncData(context)
如果需要服務(wù)端渲染,首次渲染時一定要使用這個方法遮晚。它可以在渲染組件前異步獲取數(shù)據(jù)性昭。asyncData傳入context參數(shù),可以獲取一些信息鹏漆,如:
export default {
asyncData(ctx){
ctx.app // 根實(shí)例
ctx.route // 路由實(shí)例
ctx.params // 路由參數(shù)
ctx.query // 路由問號后的參數(shù)
ctx.error // 錯誤處理方法
}
}
使用這個方法時要注意巩梢,如果由于服務(wù)器或api錯誤導(dǎo)致無法渲染创泄,就要做好容錯機(jī)制艺玲,可以使用context.error方法括蝠。我們可以這樣做:
async asyncData(ctx){
try {
throw new Error()
} catch {
ctx.error( {statusCode: 500, message: '服務(wù)器開小差了~'} ) // 這里的statusCode參數(shù)必須是http狀態(tài)碼
}
}
此時,錯誤頁可以通過/layout/error.vue自定義饭聚。
注意:該方法在服務(wù)端執(zhí)行忌警,返回的數(shù)據(jù)與data()返回的數(shù)據(jù)合并。該方法在組件初始化前被調(diào)用秒梳,所以不能通過this引用實(shí)例對象法绵。
5. head()
用于更新頭部信息title/descripe等,可以通過this獲取組件數(shù)據(jù)酪碘。
6. middleware()
在特定頁面實(shí)戰(zhàn)中間件使用axios請求數(shù)據(jù):
(1)nuxt項(xiàng)目默認(rèn)安裝axios朋譬,所以只要安裝proxy即可
npm install @nuxtjs/proxy
(2)在nuxt.config.js中加上:
export default {
modules: [
'@nuxtjs/axios',
'@nuxtjs/proxy'
],
proxy: {
'./api': {
target: 'http://www.xxx.com',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
(3)頁面中使用
import axios from 'axios'
export default {
data () {
return {
page: 0
}
},
async asyncData () {
let data = await axios.get('http://localhost:3000/api/admin/list')
return {
page: data.data.page
}
},
}
采用 import axios from 'axios'
方式引入axios時,接口參數(shù)前須加baseURL兴垦。
5. 使用scss
(1)安裝sass
npm i node-sass sass-loader scss-loader --save-dev
(2)如果要全局使用某個scss文件徙赢,要借助sass-resources-loader,還需要在nuxt.config.js的build配置中調(diào)整導(dǎo)出的loader配置:
export default {
build: {
extend(config, { isDev, isClient }){
const sassResourcesLoader = {
loader: 'sass-resources-loader',
options: {
resources: [
// 填寫需要全局注入scss的文件
'assets/styles/mixins.scss'
]
}
}
// 修改 scss sass 引用的 loader探越。
config.module.rules.forEach((rule) => {
if (rule.test.toString() === '/\\.vue$/') {
rule.options.loaders.sass.push(sassResourcesLoader)
rule.options.loaders.scss.push(sassResourcesLoader)
}
if (['/\\.sass$/', '/\\.scss$/'].indexOf(rule.test.toString()) !== -1) {
rule.use.push(sassResourcesLoader)
}
})
}
}
}
6. nuxt和vue的區(qū)別
(1)路由
nuxt按照 pages 文件夾的目錄結(jié)構(gòu)自動生成路由
vue需在 src/router/index.js 手動配置路由
(2)入口頁面
nuxt頁面入口為 layouts/default.vue
vue頁面入口為 src/App.vue
(3)webpack配置
nuxt內(nèi)置webpack狡赐,允許根據(jù)服務(wù)端需求,在 nuxt.config.js 中的build屬性自定義構(gòu)建webpack的配置钦幔,覆蓋默認(rèn)配置枕屉。
vue關(guān)于webpack的配置存放在build文件夾下。
7. 編譯過程
(1)加載nuxt.config.js鲤氢;
(2)初始化nuxt搀擂,builder,開始執(zhí)行構(gòu)建卷玉;
(3)準(zhǔn)備模板使用的參數(shù)哥倔,然后根據(jù)模板生成真正的webpack編譯的js;
(4)分別執(zhí)行客戶端編譯和服務(wù)端編譯揍庄,生成最終的js腳本咆蒿;
(5)編譯成功后,就需要啟動服務(wù)蚂子,監(jiān)聽端口沃测,這個是在npm run start中實(shí)現(xiàn)的。
關(guān)于nuxt.js先寫這些了食茎,更多內(nèi)容還是要去看官網(wǎng)文檔哦~
關(guān)注微信公眾號【CC前端手記】一起學(xué)更多前端小知識吧~