vue-cli3使用vue-skeleton-webpack-plugin骨架屏插件

搜索發(fā)現(xiàn)有下面兩個(gè)骨架屏插件(方案)

  • page-skeleton-webpack-plugin
  • vue-skeleton-webpack-plugin

page-skeleton-webpack-plugin

page-skeleton-webpack-plugin是餓了么團(tuán)隊(duì)開發(fā)的,但目前好像已經(jīng)停止維護(hù)了,所以入坑需謹(jǐn)慎。這個(gè)插件的優(yōu)點(diǎn)是可以自動(dòng)生成骨架屏。但是它不支持hash路由,不適用項(xiàng)目,所以采用下面的方案。關(guān)于這個(gè)插件的使用可以看官方文檔,或者參考一下這篇文章

vue-skeleton-webpack-plugin

vue-skeleton-webpack-plugin項(xiàng)目上提供了很多示例,但實(shí)際用起來卻有很多問題。而且這個(gè)插件需要自己實(shí)現(xiàn)骨架屏頁(yè)面。根據(jù)項(xiàng)目里的示例(vue-cli3)進(jìn)行配置。根據(jù)issue對(duì)不同頁(yè)面顯示不同骨架屏進(jìn)行了處理。

配置

// 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
}

其他配置項(xiàng)可以看文檔,這里我踩的幾個(gè)坑:

  1. entry入口的名字,示例里寫的是app,但我的項(xiàng)目里是index
  2. 示例中將main.js做了這樣的處理,目的是在css文件加載完成時(shí)再掛載Vue,以解決我下面說的白屏問題。具體可以參考項(xiàng)目的issue#62。但是可能是因?yàn)轫?xiàng)目配置的緣故,找不到window.STYLE_READY,導(dǎo)致骨架屏不消失,最后沒改動(dòng)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();
}
  1. 最后是在開發(fā)環(huán)境css無效的問題,issue中也有提到,需要在開發(fā)環(huán)境抽離css。下次讓設(shè)計(jì)師小哥給張骨架屏的圖好了,就不用寫css了。

上述兩個(gè)插件的原理都是一樣的。假設(shè)Vue掛載的元素是<div id="app"></div>,如果我們?cè)谶@個(gè)元素寫一些內(nèi)容,vue未加載完成時(shí)就會(huì)顯示在頁(yè)面中;當(dāng)vue掛載時(shí),會(huì)刪除<div id="app"></div>內(nèi)的內(nèi)容。我們可以通過這個(gè)原理實(shí)現(xiàn)Vue框架的骨架屏。
但是個(gè)人認(rèn)為這個(gè)方案其實(shí)有些問題:

  1. 無法控制骨架屏消失的時(shí)機(jī),如果我希望在首屏加載數(shù)據(jù)時(shí)顯示骨架屏,加載完后消失,基于這樣的原理很難實(shí)現(xiàn)
  2. 在Vue掛載到頁(yè)面顯示內(nèi)容還有一定的白屏?xí)r間
  3. 無法實(shí)現(xiàn)局部骨架屏,在頁(yè)面上顯示局部骨架屏代替loading效果

即使這樣,這個(gè)方案其實(shí)已經(jīng)使用大多數(shù)情況了。對(duì)于SPA來說,一般只有首頁(yè)加載較久,切換“頁(yè)面”時(shí)幾乎不需要等待時(shí)間,所以我們只需要在首屏加載骨架屏。但我們不知道用戶第一次進(jìn)入的是哪個(gè)頁(yè)面,所以我們需要根據(jù)路由判斷當(dāng)前頁(yè)面,加載不同的骨架屏。

不能自動(dòng)生成骨架屏是個(gè)硬傷,如果頁(yè)面更新,也要去維護(hù)骨架屏。讓設(shè)計(jì)師小哥切個(gè)圖是個(gè)不錯(cuò)的方法,但我們還是要追求自動(dòng)化。

以后的優(yōu)化目標(biāo)應(yīng)該是

  • 自動(dòng)化生成骨架屏
  • 骨架屏動(dòng)畫
  • 可以控制骨架屏消失的時(shí)機(jī)
  • 局部骨架屏,代替loading效果

參考文章:

Vue頁(yè)面骨架屏注入實(shí)踐
為vue項(xiàng)目添加骨架屏
餓了么的 PWA 升級(jí)實(shí)踐

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 這是一個(gè)基于 Vue 的 webpack 插件,為單頁(yè)/多頁(yè)應(yīng)用生成骨架屏 skeleton,減少白屏?xí)r間,在頁(yè)面...
    world_7735閱讀 1,341評(píng)論 0 0
  • Vue項(xiàng)目骨架屏注入實(shí)踐 相比于早些年前后端代碼緊密耦合、后端工程師還得寫前端代碼的時(shí)代,如今已發(fā)展到前后端分離,...
    萱萱暮雨閱讀 1,857評(píng)論 0 6
  • 前言 為了前端體驗(yàn)更加友好,減緩用戶的焦慮情緒,提升項(xiàng)目質(zhì)量等,我們?cè)陧?xiàng)目里面可以使用骨架屏,提前渲染出來一個(gè)跟正...
    Yinzhishan閱讀 13,809評(píng)論 12 19
  • 前端開發(fā)是與用戶聯(lián)系最為密切的職位,用戶體驗(yàn)是最值得關(guān)注的問題。現(xiàn)在越來越多的APP采用了骨架屏,隨著前端SPA單...
    js_冠榮閱讀 3,171評(píng)論 4 2
  • 在實(shí)現(xiàn) egg + vue 服務(wù)端渲染工程化實(shí)現(xiàn)之前,我們先來看看前面兩篇關(guān)于Webpack構(gòu)建和Egg的文章: ...
    hubcarl閱讀 6,129評(píng)論 0 19

友情鏈接更多精彩內(nèi)容