NUXT SSR初級(jí)入門筆記(小結(jié))
nuxt 是基于 vue 開發(fā)的一個(gè)應(yīng)用框架,最常用的就是拿來做 ssr。那么什么是 ssr 呢,這就要提及一個(gè)相對(duì)的概念:csr。
CSR & SSR
web網(wǎng)頁(yè)開發(fā)從之前的 jsp,php 轉(zhuǎn)向現(xiàn)在的三大框架 angular react vue,其實(shí)就是從 csr 到 ssr 的轉(zhuǎn)變,即從服務(wù)端渲染轉(zhuǎn)而變?yōu)榭蛻舳虽秩尽?/p>
有使用經(jīng)驗(yàn)的大概知道,例如之前的 php 開發(fā),是將網(wǎng)頁(yè)內(nèi)容和服務(wù)端代碼邏輯寫在一起的,在客戶端請(qǐng)求時(shí),服務(wù)端經(jīng)過 php 引擎的渲染生成完整的 html 頁(yè)面再返回給客戶端,這種渲染出的頁(yè)面在瀏覽器中右鍵查看源代碼都是能看見 頁(yè)面全部的 html 代碼的。而客戶端渲染如 vue,返回的就只有一個(gè)掛在 app 節(jié)點(diǎn)的 html文件和一個(gè) js 文件,頁(yè)面的內(nèi)容都是在客戶端的 js 渲染生成的。所以 渲染 html 文本所在的位置就是 CSR(客戶端渲染) 和 SSR(服務(wù)端渲染) 最本質(zhì)的區(qū)分 。
既然web開發(fā)從 ssr 過渡到了 csr,那我們?yōu)槭裁从衷偃プ?ssr 呢,這就要涉及到雙方的優(yōu)缺了:
SSR:
優(yōu)點(diǎn):
便于 SEO,渲染完整的 html 更利于搜索引擎的抓取。
頁(yè)面加載的白屏?xí)r間短(幾乎沒有)。
缺點(diǎn):
每加載一個(gè)頁(yè)面都要對(duì)服務(wù)器發(fā)起一次請(qǐng)求,服務(wù)器的渲染負(fù)荷重,請(qǐng)求緩慢。
每次加載都會(huì)刷新頁(yè)面,即使只是頁(yè)面中的小區(qū)域需要改變。
CSR:
優(yōu)點(diǎn):
頁(yè)面具有優(yōu)秀的性能,更利于頁(yè)面交互。
缺點(diǎn):
不利于SEO
首頁(yè)初始化加載白屏?xí)r間長(zhǎng)。
在我們普遍使用三大框架的今天,如果我們的頁(yè)面需要對(duì) SEO 的良好支持,這就需要我們做 ssr 了。 NUXT 項(xiàng)目的初始化
使用以下命令調(diào)用腳手架生成項(xiàng)目,腳手架選項(xiàng)按需選擇就可以了:
npx create-nuxt-app <項(xiàng)目名>
生成的目錄結(jié)構(gòu)如下:
.nuxt
運(yùn)行緩存目錄
assets
資源目錄,用于存放如 css 文件,js 文件,圖片
components
組件目錄,用于存放 vue 組件
layouts
布局目錄,用于設(shè)置布局,文件名即為布局名
在 pages 目錄里的組件可以通過 layout 屬性指定布局組件,不指定默認(rèn)為 default。
布局組件中使用 <nuxt />
標(biāo)簽指定應(yīng)用布局時(shí),page 組件所在的位置。
middleware
中間件目錄,用于設(shè)置中間件函數(shù),文件名即為中間件名
在 pages 目錄里的組件可以通過 middleware 屬性指定中間件函數(shù),中間件會(huì)在組件渲染前執(zhí)行
pages
頁(yè)面目錄,用于設(shè)置路由頁(yè)面,目錄下的 vue 文件會(huì)自動(dòng)生成相應(yīng)的路由配置
如以下目錄結(jié)構(gòu)對(duì)應(yīng)的配置:
pages/ --| _slug/ -----| comments.vue -----| index.vue --| users/ -----| _id.vue --| index.vue router: { routes: [ { name: 'index', path: '/', component: 'pages/index.vue' }, { name: 'users-id', path: '/users/:id?', component: 'pages/users/_id.vue' }, { name: 'slug', path: '/:slug', component: 'pages/_slug/index.vue' }, { name: 'slug-comments', path: '/:slug/comments', component: 'pages/_slug/comments.vue' } ] }
nuxt 中使用 <nuxt-link>
代替了 <router-link>
nuxt 會(huì)為 page 組件提供額外的配置項(xiàng),常用到的如下:
- layout 指定當(dāng)前頁(yè)面使用的布局(layouts 根目錄下的布局文件)。
- validate 校驗(yàn)方法用于校驗(yàn)動(dòng)態(tài)路由的參數(shù)。
- middleware 指定頁(yè)面的中間件函數(shù),中間件函數(shù)會(huì)在頁(yè)面渲染之前被調(diào)用,也可以指定為middleware文件夾內(nèi)的中間件名。
- asyncData 支持異步數(shù)據(jù)處理,拿來為 page 組件請(qǐng)求異步數(shù)據(jù),返回對(duì)象中的 data 會(huì)覆蓋到組件的 data 中。
- fetch 用于在渲染頁(yè)面之前獲取數(shù)據(jù)填充應(yīng)用的狀態(tài)樹(store)。不同的是 fetch 方法不會(huì)設(shè)置組件的數(shù)據(jù)。
plugins
插件目錄,用于引入第三方模塊,
如 element-ui.js:
import Vue from 'vue' import Element from 'element-ui' import locale from 'element-ui/lib/locale/lang/en' Vue.use(Element, { locale })
然后可以在 nuxt.config.js 中的 plugins 中引入:
plugins: [ '@/plugins/element-ui' ],
server
服務(wù)端目錄
static
靜態(tài)文件目錄
store
vuex目錄,index.js 為主文件,其他文件默認(rèn)會(huì)配置成 module 模塊,默認(rèn)啟用 namespace。
文件形式為:
export const state = () => ({ // state }) export const actions = { // actions } export const mutations = { // mutations }
在 index.js 的 actions 中可以配置 nuxtServerInit,可以用來將數(shù)據(jù)從服務(wù)端傳到客戶端。
具體使用
創(chuàng)建項(xiàng)目如下:
運(yùn)行初始項(xiàng)目,效果如下:
使用布局
在 layouts 下新建文件 myLayout.vue
<template> <div> <header> <h2>I am header</h2> </header> <main> <nuxt /> </main> <footer> <h2>I am footer</h2> </footer> </div> </template>
然后我們?cè)?pages 下新建文件 layoutDemo.vue
<template> <div> <h1>I am layout demo</h1> </div> </template> <script> export default { layout: 'myLayout' } </script>
訪問 localhost:3000/layoutDemo,布局效果如下:
使用中間件
例如我們實(shí)現(xiàn)一個(gè)未登錄攔截跳轉(zhuǎn)的中間件:
在 middleware 中新建 auth.js
export default function (ctx) { // eslint-disable-next-line no-constant-condition if (true) { // ctx 判斷得到未登錄 ctx.redirect({ path: '/' }) } }
再在 layoutDemo.vue 中加上 middleware: 'auth'
,這樣訪問該頁(yè)面就會(huì)攔截跳轉(zhuǎn)回主頁(yè)面。
用 asyncData 實(shí)現(xiàn) ssr
我們?cè)僭?pages 中新建頁(yè)面 ssr1.vue
<template> <div> <ul> <li v-for="item of list1" :key="item"> {{ item }} </li> </ul> <ul style="margin-top: 50px"> <li v-for="item of list2" :key="item"> {{ item }} </li> </ul> </div> </template> <script> export default { layout: 'myLayout', data () { return { list1: [] } }, async created () { const { status, data: { list } } = await this.$axios.get('/list') if (status === 200) { this.list = list } }, async asyncDate () { const { status, data: { list } } = await this.$axios.get('/list') if (status === 200) { return { list2: list } } } } </script>
這里我們 list1 是用傳統(tǒng)的 vue 方式獲取異步數(shù)據(jù), list2 用 asyncData 獲取異步數(shù)據(jù)
然后我們?cè)?server 中寫接口,應(yīng)為 node 還是采用 require 的方式,如果我們想使用 import 的方式,可以安裝 babel-cli 和 babel-preset-env , 新建配置文件 .babelrc:
{ "presets": ["env"] }
然后在 package.json 里將 dev 命令加上后綴 --exec babel-node
, server 中書寫 node 就可以使用 import 了。
然后安裝 koa-router,在 index.js 里加入以下代碼:
import Router from 'koa-router' // 以下代碼加在 start 函數(shù)內(nèi)的 原有的 app.use 之前 const router = new Router() router.get('/list', (ctx) => { ctx.body = { list: ['a', 'b', 'c'] } }) app.use(router.routes()).use(router.allowedMethods())
然后訪問頁(yè)面,兩個(gè)列表都正常渲染
我們右鍵查看源代碼:
list2 通過 asyncData 的方式實(shí)現(xiàn)了 ssr。
使用 nuxtServerInit 實(shí)現(xiàn) ssr
我們新建頁(yè)面 ssr2.vue
<template> <div> <ul> <li v-for="item of $store.state.list" :key="item"> {{ item }} </li> </ul> </div> </template> <script> export default { layout: 'myLayout' } </script>
然后在 store 中新建 index.js
export const state = () => ({ list: [] }) export const mutations = { setList (state, value) { state.list = value } } export const actions = { async nuxtServerInit ({ commit }, { app }) { const { status, data: { list } } = await this.$axios.get('/list') if (status === 200) { commit('setList', list) } } }
重新 npm run dev, 訪問 localhost:3000/ssr2
查看源代碼,也正確渲染
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue實(shí)現(xiàn)播放后端flask發(fā)送的mp3文件
這篇文章主要為大家詳細(xì)介紹了vue如何實(shí)現(xiàn)播放后端flask發(fā)送的mp3文件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-01-01vuex通過getters訪問數(shù)據(jù)為undefined問題及解決
這篇文章主要介紹了vuex通過getters訪問數(shù)據(jù)為undefined問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08vue實(shí)現(xiàn)類似淘寶商品評(píng)價(jià)頁(yè)面星級(jí)評(píng)價(jià)及上傳多張圖片功能
最近在寫一個(gè)關(guān)于vue的商城項(xiàng)目,然后集成在移動(dòng)端中,開發(fā)需求中有一界面,類似淘寶商城評(píng)價(jià)界面!接下來通過本文給大家分享vue實(shí)現(xiàn)類似淘寶商品評(píng)價(jià)頁(yè)面星級(jí)評(píng)價(jià)及上傳多張圖片功能,需要的朋友參考下吧2018-10-10elementUI如何動(dòng)態(tài)給el-tree添加子節(jié)點(diǎn)數(shù)據(jù)children詳解
element-ui 目前基本成為前端pc網(wǎng)頁(yè)端標(biāo)準(zhǔn)ui框架,下面這篇文章主要給大家介紹了關(guān)于elementUI如何動(dòng)態(tài)給el-tree添加子節(jié)點(diǎn)數(shù)據(jù)children的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11mockjs+vue頁(yè)面直接展示數(shù)據(jù)的方法
這篇文章主要介紹了mockjs+vue頁(yè)面直接展示數(shù)據(jù)的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12Vue數(shù)據(jù)更新但頁(yè)面沒有更新的多種情況問題及解決
這篇文章主要介紹了Vue數(shù)據(jù)更新但頁(yè)面沒有更新的多種情況問題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07WebStorm啟動(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-12vue實(shí)現(xiàn)pdf文件發(fā)送到郵箱功能的示例代碼
這篇文章主要介紹了vue實(shí)現(xiàn)pdf文件發(fā)送到郵箱功能,實(shí)現(xiàn)代碼包括對(duì)郵箱格式內(nèi)容是否為空的驗(yàn)證方法,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05element el-table 表格限制多選個(gè)數(shù)功能
這篇文章主要介紹了element el-table 表格限制多選個(gè)數(shù)功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-03-03