在我看來服務端的主要痛點就是資料的訪問,有各種不同的解決方法但是哪一種都感覺不夠完美。
這裡通過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服務區快取分為頁面快取 組建快...