博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Vue单页面骨架屏实践
阅读量:6196 次
发布时间:2019-06-21

本文共 4021 字,大约阅读时间需要 13 分钟。

github 地址:

演示地址:

文档地址:

关于骨架屏介绍

骨架屏的作用主要是在网络请求较慢时,提供基础占位,当数据加载完成,恢复数据展示。这样给用户一种很自然的过渡,不会造成页面长时间白屏或者闪烁等情况。 常见的骨架屏实现方案有ssr服务端渲染和prerender两种解决方案。这里主要通过代码为大家展示如何一步步做出这样一个骨架屏:

clipboard.png

prerender 渲染骨架屏

本组件库骨架屏的实现也是基于预渲染去实现的,有关于预渲染更详细的介绍请参考这篇文章:处理 Vue 单页面 Meta SEO的另一种思路 下面我们主要介绍其实现步骤,首先我们也是需要配置webpack-plugin,不过已经有实现好的prerender-spa-plugin可用

var path = require('path')var PrerenderSpaPlugin = require('prerender-spa-plugin')module.exports = {  // ...  plugins: [    new PrerenderSpaPlugin(      // Absolute path to compiled SPA      path.join(__dirname, '../dist'),      // List of routes to prerender      ['/']    )  ]}

然后写好我们的骨架屏文件main.skeleton.vue

当初次进入页面的时候我们需要显示骨架屏,数据加载完,我们需要移除骨架屏:

ssr 渲染骨架屏

下面我用我灵魂画师的笔法,画出了大致的过程:

clipboard.png

首先创建我们的skeleton.entry.js

import Vue from 'vue';import Skeleton from './skeleton.vue';export default new Vue({    components: {        Skeleton    },    template: '
'});

当然这里的skeleton.vue使我们事先写好的骨架屏组件,看起来可能是这样:

然后我们需要的是能把skeleton.entry.js编译成服务端渲染可用的bundle文件,所以我们需要有个编译骨架屏的webpack.ssr.conf.js文件:

const path = require('path');const merge = require('webpack-merge');const baseWebpackConfig = require('./webpack.base.conf');const nodeExternals = require('webpack-node-externals');function resolve(dir) {    return path.join(__dirname, dir);}module.exports = merge(baseWebpackConfig, {    target: 'node',    devtool: false,    entry: {        app: resolve('./src/skeleton.entry.js')    },    output: Object.assign({}, baseWebpackConfig.output, {        libraryTarget: 'commonjs2'    }),    externals: nodeExternals({        whitelist: /\.css$/    }),    plugins: []});

接下来最终的步骤,就是编写我们的webpackPlugin,我们期望我们的webpackPlugin可以帮我们把入口文件编译成bundle,然后再通过vue-server-renderer来render bundle,最终产出响应的html片段和css片段,这里贴出核心代码:

// webpack start to work    var serverCompiler = webpack(serverWebpackConfig);    var mfs = new MFS();    // output to mfs    serverCompiler.outputFileSystem = mfs;    serverCompiler.watch({}, function (err, stats) {        if (err) {            reject(err);            return;        }        stats = stats.toJson();        stats.errors.forEach(function (err) {            console.error(err);        });        stats.warnings.forEach(function (err) {            console.warn(err);        });        var bundle = mfs.readFileSync(outputPath, 'utf-8');        var skeletonCss = mfs.readFileSync(outputCssPath, 'utf-8');        // create renderer with bundle        var renderer = createBundleRenderer(bundle);        // use vue ssr to render skeleton        renderer.renderToString({}, function (err, skeletonHtml) {            if (err) {                reject(err);            }            else {                resolve({skeletonHtml: skeletonHtml, skeletonCss: skeletonCss});            }        });    });

最后一步,我们对产出的html片段, css片段进行组装,产出最终的html,所以我们需要监听webpack 的编译挂载之前的事件:

compiler.plugin('compilation', function (compilation) {    // add listener for html-webpack-plugin    compilation.plugin('html-webpack-plugin-before-html-processing', function (htmlPluginData, callback) {        ssr(webpackConfig).then(function (ref) {            var skeletonHtml = ref.skeletonHtml;            var skeletonCss = ref.skeletonCss;            // insert inlined styles into html            var headTagEndPos = htmlPluginData.html.lastIndexOf('');            htmlPluginData.html = insertAt(htmlPluginData.html, (""), headTagEndPos);            // replace mounted point with ssr result in html            var appPos = htmlPluginData.html.lastIndexOf(insertAfter) + insertAfter.length;            htmlPluginData.html = insertAt(htmlPluginData.html, skeletonHtml, appPos);            callback(null, htmlPluginData);        });    }); });

关于:

作者:monkeyWang

本文参考文章:为vue项目添加骨架屏

本文源码详见:

本人主页:

微信公众号:前端知识铺

会不定期推送前端技术文章,欢迎关注

转载地址:http://gpyca.baihongyu.com/

你可能感兴趣的文章
web -- Angularjs 笔记
查看>>
洛谷——P1348 Couple number
查看>>
ios之coredata(一)
查看>>
KVO实现自定义文件复制进度展示
查看>>
hadoop3.0.0测验
查看>>
事件:限制类型能力
查看>>
HTML标签,CSS简介
查看>>
Android图片采样缩放
查看>>
angular smart-table组件如何定制化之初步研究
查看>>
APPium-python实例(记录)
查看>>
coredata
查看>>
MongoDB概述
查看>>
Loj10022 埃及分数(迭代加深搜索IDDFS)
查看>>
linux 调试 之printf
查看>>
常用STL用法总结
查看>>
初探验证码识别
查看>>
FFmpeg详解
查看>>
聊聊自己的职业规划这个件事
查看>>
Map小结
查看>>
099、如何访问Service (Swarm06)
查看>>