骨架屏的用户感知比loading更好,此前看过不少专栏以及文章,这次实践中仍是遇到须要学习的部分。
对于骨架屏或者占位符学习了Vue页面骨架屏注入实践,经过服务器渲染出静态页面,在js加载完以前进行首屏加载是感知比较合理的一个选择。css
包括由于可能信息面不全,对插件源码进行了详细解读,但愿对于将要在项目中搭建骨架屏的小伙伴们有所帮助。
这次使用的vue版本是2.4.5所以vue-server-renderer也须要使用同一个版本html
vue-skeleton-webpack-plugin骨架屏与page-skeleton-webpack-plugin骨架屏生成插件
基于vue和webpack的skeleton插件
以上参考文章里有注入骨架屏的原理与知识,在此就不搬运了,感谢以上巨人。
vue-skeleton-webpack-plugin插件GITHUB地址前端
vue-skeleton-webpack-pluginvue
主要利用这个骨架屏组件 以及他依赖的其余组件 此组件我使用1.22版本,最新的将插件提供的loader放到了非主要API部分,所以在本文章中未使用此loader,以防版本升级将此loader删去。
vue-server-renderernode
熟悉ssr的小伙伴对这个插件都不陌生,经过其API createBundleRenderer建立render进行渲染,具体参考[Vue页面骨架屏注入实践][5]。 **注意点:vue与vue-server-renderer要使用同一个版本,不然会报错**
extract-text-webpack-pluginwebpack
这也是比较重要的一个插件,若是你的脚手架没有对html与css进行分离,那么你的样式(除了内联样式之外)将没法被应用,后续将会对此讲解。
在你的webpack配置文件的plugins 加入插件,为了节省性能我只在prod的时候进行plugins插入,开发模式配置以路由的模式进行开发,后续会详解。git
webpackConfig.plugins.push( new SkeletonWebpackPlugin({ webpackConfig: require('./webpack.skeleton.conf'), //主要的配置在个部分 quiet: true, minimize: true, /**router: { mode: 'hash', routes: skeletonPluginRoutes //此部分配置是SPA(单页面)多路由脚手架配置 }**/ }));
webpack.skeleton.conf.jsgithub
...//以上常规配置不写明 let merge = require('webpack-merge'); let path = require('path') let merge = require('webpack-merge') let config = require('../config') let utils = require('./utils') let baseWebpackConfig = require('./webpack.base.conf') let SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin'); let 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, module: {}, entry: { 'key':'../entry-skeleton.js',//这是你骨架屏入口文件的map,注意这里的key必须与你在webpack里模块的入口文件相同 'key':value,//对应的键值是你的骨架屏入口文件 }, output: Object.assign({}, baseWebpackConfig.output, { libraryTarget: 'commonjs2' }), plugins: [] }); //若是项目中没有样式与html的分离,能够扎到本身rules配置的.vue loader 进行开启 skeletonWebpackConfig.module.rules[1].options.loaders = utils.cssLoaders({ sourceMap: sourceMapEnabled, extract: true }); module.exports = skeletonWebpackConfig
配置此config文件最重要的web
entry-skeleton.jsvue-cli
import Vue from 'vue' import homeSkeleton from './home.skeleton.vue'; // import indexOverViewSkeleton from './indexOverView.skeleton.vue'; export default new Vue({ components: { homeSkeleton, // indexOverViewSkeleton }, template: `<homeSkeleton id="homeSkeleton" style="display:none"/>` });
只是简单的VUE入口文件,依旧要注意VUE的语法与规则,好比template只容许存在一个根元素
webpackConfig.plugins.push( new SkeletonWebpackPlugin({ webpackConfig: require('./webpack.skeleton.conf'), quiet: true, minimize: true, router: { mode: 'hash', routes: [{ path:'/home', //你但愿这个路由页面时出现骨架屏 skeletonId:'homeSkeleton', //在skeleton入口文件里配置的id entryName:'key' //webpack打包时你入口文件的entryName,应与在plugin 入口文件同样的MAPkey一致 },{ path:'/main', //你但愿这个路由页面时出现骨架屏 skeletonId:'mainSkeleton', //在skeleton入口文件里配置的id entryName:'key' //webpack打包时你入口文件的entryName,应与在plugin 入口文件同样的MAPkey一致 },] } }));
entry-skeleton.js
import Vue from 'vue' import homeSkeleton from './home.skeleton.vue'; import indexOverViewSkeleton from './indexOverView.skeleton.vue'; export default new Vue({ components: { homeSkeleton, indexOverViewSkeleton }, template: `<div> <indexOverViewSkeleton id="indexOverViewSkeleton" style="display:none"/> <homeSkeleton id="homeSkeleton" style="display:none"/> </div>` });
一、保持本身的entryName,config里entryKey与webpack脚手架入口文件的key一致
二、开启样式分离!!!!!!!!重要的事情说三遍
三、由于插件经历了几个版本的更新,目前版本是接受loader的,但配置已经扁平化,因此建议不适用插件提供的loader配置。
四、省去了笔者部分根据脚手架配置的自动获取入口的代码,使用手写的,减小配置,可以让脚手架作的事情,咱们就不要作了哦!!!笔者的建议。
这篇小小的笔记先介绍配置文件吧~~~但愿对你们有所帮助,也很感谢网上的各位码字做者提供的思路。看了插件的源码思路也很清晰,对于骨架屏的原理有了更深的理解。鸭,到点去敷面膜了,但愿本身有一天也能够开源一款前端插件,成为皮肤最好的前端。哈哈哈哈哈哈。