github 地址: VV-UI/VV-UI
演示地址: vv-ui
文檔地址:skeleton
關于骨架屏介紹骨架屏的作用主要是在網絡請求較慢時,提供基礎占位,當數據加載完成,恢復數據展示。這樣給用戶一種很自然的過渡,不會造成頁面長時間白屏或者閃爍等情況。 常見的骨架屏實現方案有ssr服務端渲染和prerender兩種解決方案。這里主要通過代碼為大家展示如何一步步做出這樣一個骨架屏:
prerender 渲染骨架屏本組件庫骨架屏的實現也是基于預渲染去實現的,有關于預渲染更詳細的介紹請參考這篇文章:處理 Vue 單頁面 Meta SEO的另一種思路 下面我們主要介紹其實現步驟,首先我們也是需要配置webpack-plugin,不過已經有實現好的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
當初次進入頁面的時候我們需要顯示骨架屏,數據加載完,我們需要移除骨架屏:
ssr 渲染骨架屏
下面我用我靈魂畫師的筆法,畫出了大致的過程:
首先創建我們的skeleton.entry.js
import Vue from "vue"; import Skeleton from "./skeleton.vue"; export default new Vue({ components: { Skeleton }, template: "" });
當然這里的skeleton.vue使我們事先寫好的骨架屏組件,看起來可能是這樣:
然后我們需要的是能把skeleton.entry.js編譯成服務端渲染可用的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,最終產出響應的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}); } }); });
最后一步,我們對產出的html片段, css片段進行組裝,產出最終的html,所以我們需要監聽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); }); }); });關于:
作者:monkeyWang
本文參考文章:為vue項目添加骨架屏
本文源碼詳見:VV-UI/VV-UI
本人主頁:monkeyWang
微信公眾號:前端知識鋪
會不定期推送前端技術文章,歡迎關注
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/112864.html
github 地址: VV-UI/VV-UI 演示地址: vv-ui 文檔地址:skeleton 關于骨架屏介紹 骨架屏的作用主要是在網絡請求較慢時,提供基礎占位,當數據加載完成,恢復數據展示。這樣給用戶一種很自然的過渡,不會造成頁面長時間白屏或者閃爍等情況。 常見的骨架屏實現方案有ssr服務端渲染和prerender兩種解決方案。這里主要通過代碼為大家展示如何一步步做出這樣一個骨架屏: show...
github 地址: VV-UI/VV-UI 演示地址: vv-ui 文檔地址:skeleton 關于骨架屏介紹 骨架屏的作用主要是在網絡請求較慢時,提供基礎占位,當數據加載完成,恢復數據展示。這樣給用戶一種很自然的過渡,不會造成頁面長時間白屏或者閃爍等情況。 常見的骨架屏實現方案有ssr服務端渲染和prerender兩種解決方案。這里主要通過代碼為大家展示如何一步步做出這樣一個骨架屏: show...
摘要:如何在下搭建多模塊單模塊多路由骨架屏前言骨架屏的用戶感知比更好,此前看過很多專欄以及文章,此次實踐中還是遇到需要學習的部分。包括因為可能信息面不全,對插件源碼進行了詳細解讀,希望對于將要在項目中搭建骨架屏的小伙伴們有所幫助。 如何在webpack+vue+vue-cli下搭建多模塊/單模塊多路由骨架屏 前言 骨架屏的用戶感知比loading更好,此前看過很多專欄以及文章,此次實踐中還是...
摘要:如何在下搭建多模塊單模塊多路由骨架屏前言骨架屏的用戶感知比更好,此前看過很多專欄以及文章,此次實踐中還是遇到需要學習的部分。包括因為可能信息面不全,對插件源碼進行了詳細解讀,希望對于將要在項目中搭建骨架屏的小伙伴們有所幫助。 如何在webpack+vue+vue-cli下搭建多模塊/單模塊多路由骨架屏 前言 骨架屏的用戶感知比loading更好,此前看過很多專欄以及文章,此次實踐中還是...
閱讀 1319·2021-11-24 09:38
閱讀 3256·2021-11-22 12:03
閱讀 4158·2021-11-11 10:59
閱讀 2317·2021-09-28 09:36
閱讀 1032·2021-09-09 09:32
閱讀 3411·2021-08-05 10:00
閱讀 2528·2021-07-23 15:30
閱讀 2973·2019-08-30 13:12