这篇文章主要给大家介绍了关于Vue单页面骨架屏实践的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用vue具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
关于骨架屏介绍
骨架屏的作用主要是在网络请求较慢时,提供基础占位,当数据加载完成,恢复数据展示。这样给用户一种很自然的过渡,不会造成页面长时间白屏或者闪烁等情况。 常见的骨架屏实现方案有ssr服务端渲染和prerender两种解决方案。
这里主要通过代码为大家展示如何一步步做出这样一个骨架屏:
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
<template> <p class="main-skeleton"> <w-skeleton height="80px"></w-skeleton> <p> <p class="skeleton-container"> <p class="skeleton"> <w-skeleton height="300px"></w-skeleton> </p> <w-skeleton height="45px"></w-skeleton> </p> <p class="skeleton-bottom"> <w-skeleton height="45px"></w-skeleton> </p> </p> </p> </template>
当初次进入页面的时候我们需要显示骨架屏,数据加载完,我们需要移除骨架屏:
<template> <p id="app"> <mainSkeleton v-if="!init"></mainSkeleton> <p v-else> <p class="body"></p> </p> </p> </template> <script> import mainSkeleton from './main.skeleton.vue' export default { name: 'app', data () { return { init: false } }, mounted () { // 这里模拟数据请求 setTimeout(() => { this.init = true }, 250) }, components: { mainSkeleton } } </script>
ssr 渲染骨架屏
下面我用我灵魂画师的笔法,画出了大致的过程:
首先创建我们的skeleton.entry.js
import Vue from 'vue'; import Skeleton from './skeleton.vue'; export default new Vue({ components: { Skeleton }, template: '<skeleton />' });
当然这里的skeleton.vue使我们事先写好的骨架屏组件,看起来可能是这样:
<template> <p class="skeleton-wrapper"> <header class="skeleton-header"></header> <p class="skeleton-block"></p> </p> </template>
然后我们需要的是能把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('</head>'); htmlPluginData.html = insertAt(htmlPluginData.html, ("<style>" + skeletonCss + "</style>"), 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); }); }); });
github 地址: VV-UI/VV-UI
演示地址: vv-ui
文档地址:skeleton
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
详细解答Webpack+Babel+React环境搭建(详细教程)
以上是在Vue中有关如何实现单页面骨架屏的详细内容。更多信息请关注PHP中文网其他相关文章!

JavaScript核心数据类型在浏览器和Node.js中一致,但处理方式和额外类型有所不同。1)全局对象在浏览器中为window,在Node.js中为global。2)Node.js独有Buffer对象,用于处理二进制数据。3)性能和时间处理在两者间也有差异,需根据环境调整代码。

JavaScriptusestwotypesofcomments:single-line(//)andmulti-line(//).1)Use//forquicknotesorsingle-lineexplanations.2)Use//forlongerexplanationsorcommentingoutblocksofcode.Commentsshouldexplainthe'why',notthe'what',andbeplacedabovetherelevantcodeforclari

Python和JavaScript的主要区别在于类型系统和应用场景。1.Python使用动态类型,适合科学计算和数据分析。2.JavaScript采用弱类型,广泛用于前端和全栈开发。两者在异步编程和性能优化上各有优势,选择时应根据项目需求决定。

选择Python还是JavaScript取决于项目类型:1)数据科学和自动化任务选择Python;2)前端和全栈开发选择JavaScript。Python因其在数据处理和自动化方面的强大库而备受青睐,而JavaScript则因其在网页交互和全栈开发中的优势而不可或缺。

Python和JavaScript各有优势,选择取决于项目需求和个人偏好。1.Python易学,语法简洁,适用于数据科学和后端开发,但执行速度较慢。2.JavaScript在前端开发中无处不在,异步编程能力强,Node.js使其适用于全栈开发,但语法可能复杂且易出错。

javascriptisnotbuiltoncorc; saninterpretedlanguagethatrunsonenginesoftenwritteninc.1)javascriptwasdesignedAsalightweight,解释edganguageforwebbrowsers.2)Enginesevolvedfromsimpleterterterpretpreterterterpretertestojitcompilerers,典型地提示。

JavaScript可用于前端和后端开发。前端通过DOM操作增强用户体验,后端通过Node.js处理服务器任务。1.前端示例:改变网页文本内容。2.后端示例:创建Node.js服务器。

选择Python还是JavaScript应基于职业发展、学习曲线和生态系统:1)职业发展:Python适合数据科学和后端开发,JavaScript适合前端和全栈开发。2)学习曲线:Python语法简洁,适合初学者;JavaScript语法灵活。3)生态系统:Python有丰富的科学计算库,JavaScript有强大的前端框架。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

禅工作室 13.0.1
功能强大的PHP集成开发环境

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。