我们会遇到一些情况, 当前的项目不需要服务端渲染, 那么我们又当如何快速自动化生成骨架屏呢? 带着这个问题,本章将带大家一起使用另一个美到粗暴的方式: 通过webpack 插件来实现骨架屏效果。
这里假设你的项目是通过webpack 构建生成的静态部署资源。 并且你的构建过程中使用html-webpack-plugin插件来生成你的首页HTML。
这里思路简单归纳为:
获取webpack 构建输出到dist 的 index.html 内容;通过插件替换 => 骨架屏模板重新输出新的index.html 文件这里简单期间,就直接在build 目录下创建插件。
创建一个文件Skeleton_plugin.js 插件源码:
var Skeleton_Plugin = function (options) { this.template = options.template } // 首页骨架屏 模板 var indexSkeletonTemplate = `<div id="app"> <div style="width:100%;height:50px;background: rgb(211, 219, 224);"></div> <ul class="loading-skeleton" style=""> <li> <div class="d1"></div> <div class="d2 o"></div> <div class="d2 d"></div> </li> <li> <div class="d1"></div> <div class="d2 o"></div> <div class="d2 d"></div> </li> <li> <div class="d1"></div> <div class="d2 o"></div> <div class="d2 d"></div> </li> <li> <div class="d1"></div> <div class="d2 o"></div> <div class="d2 d"></div> </li> <li> <div class="d1"></div> <div class="d2 o"></div> <div class="d2 d"></div> </li> <li> <div class="d1"></div> <div class="d2 o"></div> <div class="d2 d"></div> </li> </ul> <style> .loading-skeleton{ width:100%;height:auto;list-style: none;overflow: hidden;margin:0;padding:0; } .loading-skeleton li{ width: 40%; height: 180px; float: left; margin: 3% 7% 3% 3%; } .loading-skeleton li .d1{ width: 100%; height: 130px; background: rgb(211, 219, 224); } .loading-skeleton li .d2{ width: 100%; height: 15px; background: rgb(211, 219, 224); margin-top: 5px; } .loading-skeleton .o { float:left;width:92%;height:100px;margin:3%; background: rgb(211, 219, 224); animation: skeleton-stripes 1s linear infinite; transform-origin: left; animation: skeleton-stretch .5s linear infinite alternate; } .loading-skeleton .d { float:left;width:92%;height:100px;margin:3%; background: rgb(211, 219, 224); animation: skeleton-stripes 1s linear infinite; transform-origin: left; animation: skeleton-stretch .5s -.5s linear infinite alternate; } @keyframes skeleton-stretch { from { transform: scalex(1); } to { transform: scalex(.3); } } </style> </div>` /*** * html-webpack-plugin 提供了一系列事件: * html-webpack-plugin-before-html-generation html-webpack-plugin-before-html-processing html-webpack-plugin-alter-asset-tags html-webpack-plugin-after-html-processing html-webpack-plugin-after-emit html-webpack-plugin-alter-chunks */ Skeleton_Plugin.prototype.apply = function (compiler) { console.log('骨架屏生成中......') compiler.plugin('compilation', function (compilation) { compilation.plugin('html-webpack-plugin-before-html-processing', (htmlData, callback) => { /* * htmlData 是打包dist后 index的内容 * 然后用replace去替换掉 */ htmlData.html = htmlData.html.replace( `<div id="app"></div>`, indexSkeletonTemplate ); }) }) } module.exports = Skeleton_Plugin在你的 dev / prod config 文件中使用插件 源码如下:
....... const Skeleton_Plugin = require('./Skeleton_plugin') .............. const defaultPlugins = [ new HTMLPlugin({ template: path.join(__dirname, 'template.html') }), new Skeleton_Plugin({ template: "骨架屏生成" }), ] ......... let config = merge(baseConfig, { ...... plugins: defaultPlugins.concat([ new webpack.NoEmitOnErrorsPlugin() ]), ......... }) } module.exports = config然后 run start/build 你的项目, 发现生成的index.html 中已经嵌入了骨架屏的相关内容。
如果你是多页面应用,不同页面生成对应.html 那么你可以优化扩展插件, 根据不同的页面生成不同的骨架屏。
下图为嵌入骨架后页面初始加载效果图:
这种方式运行我们订制较为细致的骨架屏。
