一. 原理
在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;