搜索發(fā)現(xiàn)有下面兩個骨架屏插件(方案)
- page-skeleton-webpack-plugin
- vue-skeleton-webpack-plugin
page-skeleton-webpack-plugin
page-skeleton-webpack-plugin是餓了么團隊開發(fā)的尤误,但目前好像已經(jīng)停止維護了,所以入坑需謹慎席吴。這個插件的優(yōu)點是可以自動生成骨架屏彭谁。但是它不支持hash路由涩哟,不適用項目伏尼,所以采用下面的方案久窟。關(guān)于這個插件的使用可以看官方文檔,或者參考一下這篇文章
vue-skeleton-webpack-plugin
vue-skeleton-webpack-plugin項目上提供了很多示例蚂子,但實際用起來卻有很多問題沃测。而且這個插件需要自己實現(xiàn)骨架屏頁面。根據(jù)項目里的示例(vue-cli3)進行配置食茎。根據(jù)issue對不同頁面顯示不同骨架屏進行了處理蒂破。
配置
// skeleton.js
import Vue from 'vue'
import listSkeleton from './skeleton/listSkeleton'
import detailSkeleton from './skeleton/detailSkeleton'
export default new Vue({
components: {
listSkeleton,
detailSkeleton
},
template: `
<div>
<listSkeleton id="listSkeleton" style="display:none;" />
<detailSkeleton id="detailSkeleton" style="display:none;" />
</div>
`
});
// vue.config.js
configureWebpack: {
plugins: [
// 骨架屏配置
new SkeletonWebpackPlugin({
webpackConfig: {
entry: {
index: path.join(__dirname, './src/skeleton.js'),
},
},
minimize: true,
quiet: true,
router: {
mode: 'hash',
routes: [
{ path: '/', skeletonId: 'listSkeleton' },
{ path: /^\/detail/, skeletonId: 'detailSkeleton' }
]
}
}),
],
},
// 在開發(fā)模式下分離css樣式,讓骨架屏的css在開發(fā)模式下生效
css: {
extract: true
}
其他配置項可以看文檔别渔,這里我踩的幾個坑:
- entry入口的名字附迷,示例里寫的是app,但我的項目里是index
- 示例中將main.js做了這樣的處理哎媚,目的是在css文件加載完成時再掛載Vue喇伯,以解決我下面說的白屏問題。具體可以參考項目的issue#62拨与。但是可能是因為項目配置的緣故稻据,找不到
window.STYLE_READY
,導(dǎo)致骨架屏不消失截珍,最后沒改動main.js攀甚。
// main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
const app = new Vue({
components: {
App,
},
render: h => h(App),
});
window.mountApp = () => {
app.$mount('#app');
};
if (process.env.NODE_ENV === 'production') {
if (window.STYLE_READY) {
window.mountApp();
}
} else {
window.mountApp();
}
- 最后是在開發(fā)環(huán)境css無效的問題,issue中也有提到岗喉,需要在開發(fā)環(huán)境抽離css秋度。下次讓設(shè)計師小哥給張骨架屏的圖好了,就不用寫css了钱床。
上述兩個插件的原理都是一樣的荚斯。假設(shè)Vue掛載的元素是<div id="app"></div>
,如果我們在這個元素寫一些內(nèi)容查牌,vue未加載完成時就會顯示在頁面中事期;當vue掛載時,會刪除<div id="app"></div>
內(nèi)的內(nèi)容纸颜。我們可以通過這個原理實現(xiàn)Vue框架的骨架屏兽泣。
但是個人認為這個方案其實有些問題:
- 無法控制骨架屏消失的時機,如果我希望在首屏加載數(shù)據(jù)時顯示骨架屏胁孙,加載完后消失唠倦,基于這樣的原理很難實現(xiàn)
- 在Vue掛載到頁面顯示內(nèi)容還有一定的白屏時間
- 無法實現(xiàn)局部骨架屏称鳞,在頁面上顯示局部骨架屏代替loading效果
即使這樣,這個方案其實已經(jīng)使用大多數(shù)情況了稠鼻。對于SPA來說冈止,一般只有首頁加載較久,切換“頁面”時幾乎不需要等待時間候齿,所以我們只需要在首屏加載骨架屏熙暴。但我們不知道用戶第一次進入的是哪個頁面,所以我們需要根據(jù)路由判斷當前頁面慌盯,加載不同的骨架屏周霉。
不能自動生成骨架屏是個硬傷,如果頁面更新亚皂,也要去維護骨架屏诗眨。讓設(shè)計師小哥切個圖是個不錯的方法,但我們還是要追求自動化孕讳。
以后的優(yōu)化目標應(yīng)該是
- 自動化生成骨架屏
- 骨架屏動畫
- 可以控制骨架屏消失的時機
- 局部骨架屏匠楚,代替loading效果