骨架屏的用戶感知比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配置。
四、省去了筆者部分根據腳手架配置的自動獲取入口的代碼,使用手寫的,減小配置,可以讓腳手架作的事情,咱們就不要作了哦!!!筆者的建議。
這篇小小的筆記先介紹配置文件吧~~~但願對你們有所幫助,也很感謝網上的各位碼字做者提供的思路。看了插件的源碼思路也很清晰,對於骨架屏的原理有了更深的理解。鴨,到點去敷面膜了,但願本身有一天也能夠開源一款前端插件,成爲皮膚最好的前端。哈哈哈哈哈哈。