vue-cli3.0 項目內使用vue-skeleton-webpack-plugin插件根據路由來渲染不同的骨架屏

爲了前端體驗更加友好,減緩用戶的焦慮情緒,提升項目質量等,我們在項目裏面可以使用骨架屏,提前渲染出來一個跟正式頁面相似的頁面出來,減小首屏加載時間。

在vue中使用骨架屏

因爲我們的代碼會使用webpack打包,所以在我們的js下載運行之前,用戶是無法在頁面上看到信息,所以,我們要把骨架屏相關的代碼放到HTML裏面,當然,可以把代碼直接寫在html文件的<div id=’app‘></div>裏面,但是爲了維護我們進行開發時的體驗,我們在開發時可以使用一個webpack插件,來像開發組件一樣來開發骨架屏。

1.全局安裝@vue/cli(Vue CLI 3的包名稱由 vue-cli 改成了 @vue/cli

npm install -g @vue/cli

2.新建vue-skeleton項目

vue create vue-skeleton

3.添加vue-skeleton-webpack-plugin插件

npm install vue-skeleton-webpack-plugin

4.創建骨架屏文件

在src文件夾下新建skeleton目錄,並在這個目錄內新建listSkeleton.vue、detailSkeleton.vue,兩個文件內的內容如下:

<!--listSkeleton.vue -->
<template>
  <div class="container">
    <div>列表骨架屏</div>
    <img
      src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMTA4MCAyNjEiPjxkZWZzPjxwYXRoIGlkPSJiIiBkPSJNMCAwaDEwODB2MjYwSDB6Ii8+PGZpbHRlciBpZD0iYSIgd2lkdGg9IjIwMCUiIGhlaWdodD0iMjAwJSIgeD0iLTUwJSIgeT0iLTUwJSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94Ij48ZmVPZmZzZXQgZHk9Ii0xIiBpbj0iU291cmNlQWxwaGEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0T3V0ZXIxIi8+PGZlQ29sb3JNYXRyaXggaW49InNoYWRvd09mZnNldE91dGVyMSIgdmFsdWVzPSIwIDAgMCAwIDAuOTMzMzMzMzMzIDAgMCAwIDAgMC45MzMzMzMzMzMgMCAwIDAgMCAwLjkzMzMzMzMzMyAwIDAgMCAxIDAiLz48L2ZpbHRlcj48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDEpIj48dXNlIGZpbGw9IiMwMDAiIGZpbHRlcj0idXJsKCNhKSIgeGxpbms6aHJlZj0iI2IiLz48dXNlIGZpbGw9IiNGRkYiIHhsaW5rOmhyZWY9IiNiIi8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCA0NGg1MzN2NDZIMjMweiIvPjxyZWN0IHdpZHRoPSIxNzIiIGhlaWdodD0iMTcyIiB4PSIzMCIgeT0iNDQiIGZpbGw9IiNGNkY2RjYiIHJ4PSI0Ii8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCAxMThoMzY5djMwSDIzMHpNMjMwIDE4MmgzMjN2MzBIMjMwek04MTIgMTE1aDIzOHYzOUg4MTJ6TTgwOCAxODRoMjQydjMwSDgwOHpNOTE3IDQ4aDEzM3YzN0g5MTd6Ii8+PC9nPjwvc3ZnPg=="
    />
    <img
      src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMTA4MCAyNjEiPjxkZWZzPjxwYXRoIGlkPSJiIiBkPSJNMCAwaDEwODB2MjYwSDB6Ii8+PGZpbHRlciBpZD0iYSIgd2lkdGg9IjIwMCUiIGhlaWdodD0iMjAwJSIgeD0iLTUwJSIgeT0iLTUwJSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94Ij48ZmVPZmZzZXQgZHk9Ii0xIiBpbj0iU291cmNlQWxwaGEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0T3V0ZXIxIi8+PGZlQ29sb3JNYXRyaXggaW49InNoYWRvd09mZnNldE91dGVyMSIgdmFsdWVzPSIwIDAgMCAwIDAuOTMzMzMzMzMzIDAgMCAwIDAgMC45MzMzMzMzMzMgMCAwIDAgMCAwLjkzMzMzMzMzMyAwIDAgMCAxIDAiLz48L2ZpbHRlcj48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDEpIj48dXNlIGZpbGw9IiMwMDAiIGZpbHRlcj0idXJsKCNhKSIgeGxpbms6aHJlZj0iI2IiLz48dXNlIGZpbGw9IiNGRkYiIHhsaW5rOmhyZWY9IiNiIi8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCA0NGg1MzN2NDZIMjMweiIvPjxyZWN0IHdpZHRoPSIxNzIiIGhlaWdodD0iMTcyIiB4PSIzMCIgeT0iNDQiIGZpbGw9IiNGNkY2RjYiIHJ4PSI0Ii8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCAxMThoMzY5djMwSDIzMHpNMjMwIDE4MmgzMjN2MzBIMjMwek04MTIgMTE1aDIzOHYzOUg4MTJ6TTgwOCAxODRoMjQydjMwSDgwOHpNOTE3IDQ4aDEzM3YzN0g5MTd6Ii8+PC9nPjwvc3ZnPg=="
    />
  </div>
</template>

<script>
export default {
  components: {},
  data () {
    return {}
  },
  mounted () {},
  methods: {}
}
</script>

<style scoped lang="scss">
</style>
<!-- detailSkeleton.vue -->
<template>
  <div class="container">
    詳情骨架屏
    <img
      src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMTA4MCAyNjEiPjxkZWZzPjxwYXRoIGlkPSJiIiBkPSJNMCAwaDEwODB2MjYwSDB6Ii8+PGZpbHRlciBpZD0iYSIgd2lkdGg9IjIwMCUiIGhlaWdodD0iMjAwJSIgeD0iLTUwJSIgeT0iLTUwJSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94Ij48ZmVPZmZzZXQgZHk9Ii0xIiBpbj0iU291cmNlQWxwaGEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0T3V0ZXIxIi8+PGZlQ29sb3JNYXRyaXggaW49InNoYWRvd09mZnNldE91dGVyMSIgdmFsdWVzPSIwIDAgMCAwIDAuOTMzMzMzMzMzIDAgMCAwIDAgMC45MzMzMzMzMzMgMCAwIDAgMCAwLjkzMzMzMzMzMyAwIDAgMCAxIDAiLz48L2ZpbHRlcj48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDEpIj48dXNlIGZpbGw9IiMwMDAiIGZpbHRlcj0idXJsKCNhKSIgeGxpbms6aHJlZj0iI2IiLz48dXNlIGZpbGw9IiNGRkYiIHhsaW5rOmhyZWY9IiNiIi8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCA0NGg1MzN2NDZIMjMweiIvPjxyZWN0IHdpZHRoPSIxNzIiIGhlaWdodD0iMTcyIiB4PSIzMCIgeT0iNDQiIGZpbGw9IiNGNkY2RjYiIHJ4PSI0Ii8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCAxMThoMzY5djMwSDIzMHpNMjMwIDE4MmgzMjN2MzBIMjMwek04MTIgMTE1aDIzOHYzOUg4MTJ6TTgwOCAxODRoMjQydjMwSDgwOHpNOTE3IDQ4aDEzM3YzN0g5MTd6Ii8+PC9nPjwvc3ZnPg=="
    />
  </div>
</template>

<script>
export default {
  components: {},
  data () {
    return {}
  },
  mounted () {},
  methods: {}
}
</script>

<style scoped lang="scss">
</style>

在這個頁面裏面我們可以根據需要來編寫代碼,最好使用樣式或者base64的圖片,以減少初始的請求。 

5.新建一個Skeleton.js入口文件

main.js同級新建一個Skeleton.js,內容如下:

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

6.配置打包方案

在項目根目錄新建vue.config.js,在裏面配置vue-skeleton-webpack-plugin插件,並開啓css分離;

根據配置各個路由路徑對應的 Skeleton

//vue.config.js
const path = require('path')
const SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin')

module.exports = {
  configureWebpack: (config) => {
    config.plugins.push(new SkeletonWebpackPlugin({
      webpackConfig: {
        entry: {
          app: path.join(__dirname, './src/Skeleton.js')
        }
      },
      minimize: true,
      quiet: true,
      router: {
        mode: 'hash',
        routes: [
          { path: '/', skeletonId: 'listSkeleton' },
          { path: /^\/detail/, skeletonId: 'detailSkeleton' }
        ]
      }
    }))
  },
  // css相關配置
  css: {
    // 是否使用css分離插件 ExtractTextPlugin
    extract: true,
    // 開啓 CSS source maps?
    sourceMap: false,
    // 啓用 CSS modules for all css / pre-processor files.
    modules: false
  }
}

vue-skeleton-webpack-plugin插件參數說明

  • webpackConfig 必填,渲染 skeleton 的 webpack 配置對象
  • insertAfter 選填,渲染 DOM 結果插入位置,默認值爲字符串 '<div id="app">'
    • 也可以傳入 Function,方法簽名爲 insertAfter(entryKey: string): string,返回值爲掛載點字符串
  • quiet 選填,在服務端渲染時是否需要輸出信息到控制檯
  • router 選填 SPA 下配置各個路由路徑對應的 Skeleton
    • mode 選填 路由模式,兩個有效值 history|hash
    • routes 選填 路由數組,其中每個路由對象包含兩個屬性:
      • path 路由路徑 string|RegExp
      • skeletonId Skeleton DOM 的 id string
  • minimize 選填 SPA 下是否需要壓縮注入 HTML 的 JS 代碼

7.在瀏覽器中查看效果

因爲網絡快的時候,我們是不顯示骨架屏的,所以要把我們的瀏覽器網絡調慢一點(調整爲solw 3G),以方便我們開發和調試;

首頁加載時:

detail頁面加載時

我們會看到骨架屏先被渲染出來,然後纔會有我們的頁面渲染出來;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章