一. 原理
在vue的首页自动加上骨架屏代码。类似于下面:
<div id="app">
<app></app>
</div>
加上骨架屏后:
<div id="app">
<app></app>
<div>骨架屏 code</div>
</div>
在app没有加载之前先看到的是骨架屏,加载完成之后骨架屏被替换。
由于直接写在这里面代码不好管理,我们把它抽出来,在编译阶段插进去。
二、实现
1. 写骨架skeleton.html
在index.html同级目录下新建文件skeleton.html
skeleton.html用于写骨架屏页面。
<style></style>
<div>骨架屏 code</div>
<script></script>
2. 在index.html里面加入插入标识
插标识是为了编译的时候识别
即为标识标记。 <div id="app">
<app></app>
<!-- skeleton-outlet -->
</div>
3. 写骨架屏插件
在webpack.config.js同级目录下新建Skeleton.js
Skeleton.js即骨架屏插件,骨架屏插件操作:把skeleton.html读取插入index.html
代码大致如下:
const fs = require("fs");
let Skeleton = function (options) {
this.template = options.template;
};
Skeleton.prototype.apply = function (compiler) {
const skeletonpath = this.template;
compiler.plugin('compilation', compilation => {
compilation.plugin('html-webpack-plugin-before-html-processing', (htmlData, callback) => {
// 读取文件
fs.readFile(skeletonpath, "utf-8", function(error, data) {
if (error) {
callback(null, htmlData);
} else {
// 插入文件
htmlData.html = htmlData.html.replace('<!-- skeleton-outlet -->', data);
callback(null, htmlData);
}
});
});
});
};
module.exports = Skeleton;
4. 使用骨架屏插件
在webpack.config.js中引入,再插件使用。
const Skeleton = require('../../build/Skeleton');
module.exports = {
plugins: [
new Skeleton({
// 骨架路径
template: './skeleton.html'
})
]
};
运行后即可用了。
5. 优化
我们希望可以把插入标识可配置化。使用方式如下:
const Skeleton = require('../../build/Skeleton');
module.exports = {
plugins: [
new Skeleton({
outlet: '<!-- skeleton-outlet -->', // 插入标识
template: './skeleton.html' // 骨架路径
})
]
};
则Skeleton可对应调整下:
const fs = require("fs");
let Skeleton = function (options) {
this.template = options.template;
// 接受标识配置
this.outlet = options.outlet;
};
Skeleton.prototype.apply = function (compiler) {
const { template, outlet } = this;
compiler.plugin('compilation', compilation => {
compilation.plugin('html-webpack-plugin-before-html-processing', (htmlData, callback) => {
// 读取文件
fs.readFile(template, "utf-8", function(error, data) {
if (error) {
callback(null, htmlData);
} else {
// 插入文件,采用动态标识
htmlData.html = htmlData.html.replace(outlet, data);
callback(null, htmlData);
}
});
});
});
};
module.exports = Skeleton;