手记

一个vue实现多页面骨架屏vue-skeleton-webpack-plugin插件的使用

vue-skeleton-webpack-plugin这是一个基于 vue 的 webpack 插件,为单页和多页应用生成 skeleton,提升首屏展示体验。

安装

1.在package.json文件引入依赖    "vue-skeleton-webpack-plugin": "^1.1.17"

2.npm install vue-skeleton-webpack-plugin

使用

首先创建一个仅使用骨架屏组件的入口文件:
// src/components/Skeleton/entry-skeleton.js

import Vue from 'vue'
// 创建的骨架屏 Vue 实例
import SkeletonFinanceSubMenuMore from './SkeletonFinanceSubMenuMore'
import SkeletonInvestmentFinanceHome from './SkeletonInvestmentFinanceHome'
import SkeletonWalletHome from './SkeletonWalletHome'

export default new Vue({
  components: {
    SkeletonFinanceSubMenuMore,
    SkeletonInvestmentFinanceHome,
    SkeletonWalletHome
  },
  template: `
        <div>
            <SkeletonInvestmentFinanceHome id="skeleton-investmentfinancehome" style="display:none"/>
            <SkeletonFinanceSubMenuMore id="skeleton-financesubmenu-more" style="display:none"/>
            <SkeletonWalletHome id="skeleton-wallethome" style="display:none"/>
        </div>
    `
})

接下来创建一个用于服务端渲染的 webpack 配置对象,将刚创建的入口文件指定为 entry 依赖入口:
// build/webpack.skeleton.conf.js

'use strict';

const path = require('path')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const nodeExternals = require('webpack-node-externals')
const utils = require('./utils')
const config = require('../config')
const isProduction = process.env.NODE_ENV === 'production'
const sourceMapEnabled = isProduction
  ? config.build.productionSourceMap
  : config.dev.cssSourceMap

function resolve(dir) {
  return path.join(__dirname, dir)
}

let skeletonWebpackConfig = merge(baseWebpackConfig, {
  target: 'node',
  devtool: false,
  entry: {
    app: resolve('../src/components/Skeleton/entry-skeleton.js')
  },
  output: Object.assign({}, baseWebpackConfig.output, {
    libraryTarget: 'commonjs2'
  }),
  externals: nodeExternals({
    whitelist: /\.css$/
  }),
  plugins: []
})

// important: enable extract-text-webpack-plugin
skeletonWebpackConfig.module.rules[0].options.loaders = utils.cssLoaders({
  sourceMap: sourceMapEnabled,
  extract: true
}),

module.exports = skeletonWebpackConfig

在 webpack 中引入插件,在多页或单页应用中pro模式下自动插入路由规则
(运行打好的包浏览器输入配置的路由路径即可显示效果)亲测试多页显示需要配置绝对路径
(如 path: '/InvestmentFinance/FinanceSubMenu/more'; path: '/InvestmentFinance/WalletHome')

// build/webpack.prod.conf.js
const SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin')
plugins: [
// inject skeleton content(DOM & CSS) into HTML
new SkeletonWebpackPlugin({
  webpackConfig: require('./webpack.skeleton.conf'),
  quiet: true,
  minimize: true,
  router: {
    mode: 'history',
    routes: [
      {
        path: '',
        skeletonId: 'skeleton-investmentfinancehome'
      },
      {
        path: '/InvestmentFinance',
        skeletonId: 'skeleton-investmentfinancehome'
      },
      {
        path: '/InvestmentFinance/FinanceSubMenu/more',
        skeletonId: 'skeleton-financesubmenu-more'
      },
      {
        path: '/InvestmentFinance/WalletHome',
        skeletonId: 'skeleton-wallethome'
      }
    ]
  }
})
]

开发模式下开发调试骨架屏

由于 skeleton 的渲染结果在 JS 前端渲染完成后就会被替换,如何在开发时方便的查看呢? 在开发模式中插入 skeleton 对应的路由规则,使多个页面的 skeleton 能像其他路由组件一样被访问,将使开发调试变得更加方便。

//  src/router/Test /index.js

module.exports = {
  path: '/Test',
  component: (resolve) => import('@comp/EmptyTmpl').then(module => resolve(module)),
  children: [
    {
      path: 'SkeletonFinanceSubMenuMore',
      name: 'TestSkeletonFinanceSubMenuMore',
      component: (resolve) => import('@comp/Skeleton/SkeletonFinanceSubMenuMore').then(module => resolve(module)),
      meta: {
        title: 'SkeletonFinanceSubMenuMore'
      }
    },
    {
      path: 'SkeletonInvestmentFinanceHome',
      name: 'TestSkeletonInvestmentFinanceHome',
      component: (resolve) => import('@comp/Skeleton/SkeletonInvestmentFinanceHome').then(module => resolve(module)),
      meta: {
        title: 'SkeletonInvestmentFinanceHome'
      }
    },
    {
      path: 'SkeletonWalletHome',
      name: 'TestSkeletonWalletHome',
      component: (resolve) => import('@comp/Skeleton/SkeletonWalletHome').then(module => resolve(module)),
      meta: {
        title: 'SkeletonWalletHome'
      }
    }
  ]
}

 

//  src/router/index.js

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

export default new Router({
  mode: 'history',
  routes: [
    {
      path: '/',
      redirect: 'Test'
    },
    {
      path: '*',
      component: (resolve) => import(/* webpackChunkName: 'global-error-page' */'@comp/GlobalErrorPage/GlobalErrorPage').then(module => resolve(module)),
      meta: {
        title: '访问失联',
        subRoot: true,
        closeBtnVisible: true
      }
    },
    // require('./Test/index')
  ],
  scrollBehavior() {
    return {x: 0, y: 0}
  }
})


3人推荐
随时随地看视频
慕课网APP