github 地址: VV-UI/VV-UI
演示地址: vv-ui
文檔地址:skeleton
關(guān)于骨架屏介紹骨架屏的作用主要是在網(wǎng)絡(luò)請求較慢時,提供基礎(chǔ)占位,當(dāng)數(shù)據(jù)加載完成,恢復(fù)數(shù)據(jù)展示。這樣給用戶一種很自然的過渡,不會造成頁面長時間白屏或者閃爍等情況。 常見的骨架屏實現(xiàn)方案有ssr服務(wù)端渲染和prerender兩種解決方案。這里主要通過代碼為大家展示如何一步步做出這樣一個骨架屏:
prerender 渲染骨架屏本組件庫骨架屏的實現(xiàn)也是基于預(yù)渲染去實現(xiàn)的,有關(guān)于預(yù)渲染更詳細的介紹請參考這篇文章:處理 Vue 單頁面 Meta SEO的另一種思路 下面我們主要介紹其實現(xiàn)步驟,首先我們也是需要配置webpack-plugin,不過已經(jīng)有實現(xiàn)好的prerender-spa-plugin可用
var path = require("path") var PrerenderSpaPlugin = require("prerender-spa-plugin") module.exports = { // ... plugins: [ new PrerenderSpaPlugin( // Absolute path to compiled SPA path.join(__dirname, "../dist"), // List of routes to prerender ["/"] ) ] }
然后寫好我們的骨架屏文件main.skeleton.vue
當(dāng)初次進入頁面的時候我們需要顯示骨架屏,數(shù)據(jù)加載完,我們需要移除骨架屏:
ssr 渲染骨架屏
下面我用我靈魂畫師的筆法,畫出了大致的過程:
首先創(chuàng)建我們的skeleton.entry.js
import Vue from "vue"; import Skeleton from "./skeleton.vue"; export default new Vue({ components: { Skeleton }, template: "" });
當(dāng)然這里的skeleton.vue使我們事先寫好的骨架屏組件,看起來可能是這樣:
然后我們需要的是能把skeleton.entry.js編譯成服務(wù)端渲染可用的bundle文件,所以我們需要有個編譯骨架屏的webpack.ssr.conf.js文件:
const path = require("path"); const merge = require("webpack-merge"); const baseWebpackConfig = require("./webpack.base.conf"); const nodeExternals = require("webpack-node-externals"); function resolve(dir) { return path.join(__dirname, dir); } module.exports = merge(baseWebpackConfig, { target: "node", devtool: false, entry: { app: resolve("./src/skeleton.entry.js") }, output: Object.assign({}, baseWebpackConfig.output, { libraryTarget: "commonjs2" }), externals: nodeExternals({ whitelist: /.css$/ }), plugins: [] });
接下來最終的步驟,就是編寫我們的webpackPlugin,我們期望我們的webpackPlugin可以幫我們把入口文件編譯成bundle,然后再通過vue-server-renderer來render bundle,最終產(chǎn)出響應(yīng)的html片段和css片段,這里貼出核心代碼:
// webpack start to work var serverCompiler = webpack(serverWebpackConfig); var mfs = new MFS(); // output to mfs serverCompiler.outputFileSystem = mfs; serverCompiler.watch({}, function (err, stats) { if (err) { reject(err); return; } stats = stats.toJson(); stats.errors.forEach(function (err) { console.error(err); }); stats.warnings.forEach(function (err) { console.warn(err); }); var bundle = mfs.readFileSync(outputPath, "utf-8"); var skeletonCss = mfs.readFileSync(outputCssPath, "utf-8"); // create renderer with bundle var renderer = createBundleRenderer(bundle); // use vue ssr to render skeleton renderer.renderToString({}, function (err, skeletonHtml) { if (err) { reject(err); } else { resolve({skeletonHtml: skeletonHtml, skeletonCss: skeletonCss}); } }); });
最后一步,我們對產(chǎn)出的html片段, css片段進行組裝,產(chǎn)出最終的html,所以我們需要監(jiān)聽webpack 的編譯掛載之前的事件:
compiler.plugin("compilation", function (compilation) { // add listener for html-webpack-plugin compilation.plugin("html-webpack-plugin-before-html-processing", function (htmlPluginData, callback) { ssr(webpackConfig).then(function (ref) { var skeletonHtml = ref.skeletonHtml; var skeletonCss = ref.skeletonCss; // insert inlined styles into html var headTagEndPos = htmlPluginData.html.lastIndexOf(""); htmlPluginData.html = insertAt(htmlPluginData.html, (""), headTagEndPos); // replace mounted point with ssr result in html var appPos = htmlPluginData.html.lastIndexOf(insertAfter) + insertAfter.length; htmlPluginData.html = insertAt(htmlPluginData.html, skeletonHtml, appPos); callback(null, htmlPluginData); }); }); });關(guān)于:
作者:monkeyWang
本文參考文章:為vue項目添加骨架屏
本文源碼詳見:VV-UI/VV-UI
本人主頁:monkeyWang
微信公眾號:前端知識鋪
會不定期推送前端技術(shù)文章,歡迎關(guān)注
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/54507.html
github 地址: VV-UI/VV-UI 演示地址: vv-ui 文檔地址:skeleton 關(guān)于骨架屏介紹 骨架屏的作用主要是在網(wǎng)絡(luò)請求較慢時,提供基礎(chǔ)占位,當(dāng)數(shù)據(jù)加載完成,恢復(fù)數(shù)據(jù)展示。這樣給用戶一種很自然的過渡,不會造成頁面長時間白屏或者閃爍等情況。 常見的骨架屏實現(xiàn)方案有ssr服務(wù)端渲染和prerender兩種解決方案。這里主要通過代碼為大家展示如何一步步做出這樣一個骨架屏: show...
github 地址: VV-UI/VV-UI 演示地址: vv-ui 文檔地址:skeleton 關(guān)于骨架屏介紹 骨架屏的作用主要是在網(wǎng)絡(luò)請求較慢時,提供基礎(chǔ)占位,當(dāng)數(shù)據(jù)加載完成,恢復(fù)數(shù)據(jù)展示。這樣給用戶一種很自然的過渡,不會造成頁面長時間白屏或者閃爍等情況。 常見的骨架屏實現(xiàn)方案有ssr服務(wù)端渲染和prerender兩種解決方案。這里主要通過代碼為大家展示如何一步步做出這樣一個骨架屏: show...
摘要:如何在下搭建多模塊單模塊多路由骨架屏前言骨架屏的用戶感知比更好,此前看過很多專欄以及文章,此次實踐中還是遇到需要學(xué)習(xí)的部分。包括因為可能信息面不全,對插件源碼進行了詳細解讀,希望對于將要在項目中搭建骨架屏的小伙伴們有所幫助。 如何在webpack+vue+vue-cli下搭建多模塊/單模塊多路由骨架屏 前言 骨架屏的用戶感知比loading更好,此前看過很多專欄以及文章,此次實踐中還是...
摘要:如何在下搭建多模塊單模塊多路由骨架屏前言骨架屏的用戶感知比更好,此前看過很多專欄以及文章,此次實踐中還是遇到需要學(xué)習(xí)的部分。包括因為可能信息面不全,對插件源碼進行了詳細解讀,希望對于將要在項目中搭建骨架屏的小伙伴們有所幫助。 如何在webpack+vue+vue-cli下搭建多模塊/單模塊多路由骨架屏 前言 骨架屏的用戶感知比loading更好,此前看過很多專欄以及文章,此次實踐中還是...
摘要:常用于文章列表動態(tài)列表頁等相對比較規(guī)則的列表頁面。很多項目中都有應(yīng)用餓了么版本知乎等網(wǎng)站中都有應(yīng)用。歡迎討論,點個贊再走吧 骨架屏 最近在項目不時有用到骨架屏的需求,所以抽時間對骨架屏的方案作了一下調(diào)研,骨架屏的實踐已經(jīng)有很多了,也有很多人對自己的方案作了介紹.在這里按照個人的理解做了一個匯總和分類,分享給大家. 關(guān)于骨架屏(簡介) 骨架屏就是在頁面數(shù)據(jù)尚未加載前先給用戶展示出頁面的大...
閱讀 2101·2021-11-18 10:02
閱讀 2849·2021-09-04 16:41
閱讀 1141·2019-08-30 15:55
閱讀 1405·2019-08-29 17:27
閱讀 1068·2019-08-29 17:12
閱讀 2534·2019-08-29 15:38
閱讀 2853·2019-08-29 13:02
閱讀 2829·2019-08-29 12:29