關於vue服務端渲染 2 資料預訪問

2021-08-21 10:53:09 字數 2828 閱讀 9159

在我看來服務端的主要痛點就是資料的訪問,有各種不同的解決方法但是哪一種都感覺不夠完美。

這裡通過vuex來進行服務端和客戶端的資料同步,主要根據是服務端渲染完成之後如果存在store,會在window中插入乙個欄位來表示,客戶端可以通過這個欄位來直接載入。

上文裡配置router,vuex的配置方式類似

先宣告乙個vuex的工廠函式

import vue from

'vue'

import vuex from

'vuex'

import from

'./api'

//忽略實現細節,請求資料並返回乙個promise

vue.use(vuex)

export function

createstore()}

mutations:)

},actions:,id))})}

}})

}

在main裡面加入vuex

import vue from 'vue'

import from '@/router'

import from '@/store'

import from 'vuex-router-sync'

//新增的工具包,需要npm install安裝,用來同步store和router

//根元件

export

default

()=>)

}

乙個需要進行資料的元件(下文中方案2時)

}div>

template>

export default ) ,

computed:

}}script>

其實asyncdata這個名字是隨意定義的,因為他呼叫的時機需要手動編寫**實現

在server.js也就是服務端的入口檔案裡更改

//服務端的入口檔案 server.js

export

default ctx=> = ctx;

router.push(url)

router.onready(() => )

}promise.all(matchs.map(component=>)

}})).then(()=>).catch(reject)

},reject)

})}

在服務端的資料訪問很簡單,客戶端需要為不同的載入方式和使用者體驗來做不同配置。

通過元件beforemount生命週期請求資料,這個需要每個元件的路由變化需要直接更新,也就是每次變化都需要變更url來觸發元件的beformount,因為資料在第一時間是沒有請求到的,所以需要在每個元件上編寫loading並把實際**通過if-else的方式來不掛載,等待資料完成之後再掛載,優點是頁面直接變化,使用者可以在第一時間感覺到。缺點是需要每個元件新增載入指示器,並且如果不做判斷的話,在首屏的時候服務端已經做好的資料,但是在beforemount時又會進行乙個資料的載入,為了解決這個可能需要為資料固定乙個名稱。

//客戶端入口檔案 client.js

import vue from 'vue'

//注入到window裡的state轉化成客戶端可用的state

if(window.__initial_state__)

//方案1

vue.mixin(

},beforemount()=this.$options

let data=null; //把資料在computed的名稱固定為data,防止重複渲染

trycatch(e){}

if(asyncdata&&!data))

this.datapromise.then

(()=>)

catch

(e=>)

}else

if(asyncdata)

},)router.onready

(()=>)

在方案1的情況下元件應該是這樣的

《載入器 v-if="loading">else>

......

方案2

在路由發生變化的時候進行呼叫asyncdata資料載入,等待資料載入完成之後再跳轉到元件上,這時候資料已經完成,缺點是因為等待資料載入然後觸發跳轉所以過程看起來感覺更慢,需要觸發全域性的載入指示器。另外在伺服器渲染的時候因為首屏資料傳入,所以不會有問題,但是在使用純客戶端進行開發的時候,會因為首屏不觸發路由中介軟體,所以不執行資料載入丟擲錯誤,經過一次跳轉之後才會正常。

// ...忽略無關**

//方案2

vue.mixin( = this.$options

if(asyncdata)).then

(()=>).catch

((e)=>)

}else

}})router.onready

(() => )

if (!activated.length)

// 這裡如果有載入指示器(loading indicator),就觸發

promise.all(activated.map(c => )

}})).then(() => ).catch(next)

})})

具體方案根據專案不同可以靈活組合,這兩個方案僅當參考。

需要注意的點

1. actions需要返回乙個promise

2. asyncdata需要返回乙個promise

3. 頁面的展示時期是否可以得到資料

服務端渲染or預渲染

今天木有引言嚶嚶嚶 瀏覽器核心分兩個部分 渲染引擎 js引擎 解析html以構建dom樹 構建render樹 布局render樹 繪製render樹 不過有三個點需要注意 雖然能夠很快渲染出頁面,但是沒有執行react時頁面無法進行互動 獲取第乙個位元組時會更加慢一點,由於ssr需要將完整的渲染過的...

Vue之服務端渲染,資料介面

spa例項 專案中常會包含多個頁面及元件,需要用到 vue router 來進行路由控制,服務端渲染元件時,都需要從資料庫中獲取真實資料。一下強調幾個重難點 入口檔案分離 服 務端不同於客戶端,需要整個應用的 vue 例項,但可以通過不同的入口檔案來進行不同元件的操作,各取所需。其中client e...

vue服務端渲染新增快取

雖然 vue 的伺服器端渲染 ssr 相當快速,但是由於建立元件例項和虛擬 dom 節點的開銷,無法與純基於字串拼接 pure string based 的模板的效能相當。在 ssr 效能至關重要的情況下,明智地利用快取策略,可以極大改善響應時間並減少伺服器負載。vue服務區快取分為頁面快取 組建快...