Vue页面显示骨架屏

1.什么是骨架屏幕?

在页面加载数据之前,有一段空白时间,要么用loading加载,要么就用骨架屏。

2.如何快速用Vue实现骨架屏效果?

#①直接把下面的CSS代码复制,粘贴到vue项目的index.html <head>...</head>里面

<style>
  .skeleton {
    position: fixed;
    height: 100%;
    overflow: hidden;
    padding: 15px;
    box-sizing: border-box;
    background: #fff;
    width: 98%;
    top: 0;
  }
  .skeleton-nav {
    height: 110px;
    background: #eee;
    margin-bottom: 15px;
  }
  .skeleton-swiper {
    height: 440px;
    background: #eee;
    margin-bottom: 15px;
  }
  .skeleton-tabs {
    list-style: none;
    padding: 0;
    margin: 0 -15px;
    display: flex;
    flex-wrap: wrap;
  }
  .skeleton-tabs-item {
    width: 22%;
    height: 80px;
    box-sizing: border-box;
    text-align: center;
    margin-bottom: 15px;
  }
  .skeleton-tabs-item span {
    display: inline-block;
    width: 80px;
    height: 80px;
    border-radius: 55px;
    background: #eee;
  }
  .skeleton-banner {
    height: 250px;
    background: #eee;
    margin-bottom: 15px;
  }
  .skeleton-productions {
    height: 50px;
    margin-bottom: 15px;
    background: #eee;
  }
</style>

#②把下面的html代码复制,粘贴到vue项目的index.html 的 <div id=app>.....</div>里面

 1  <div data-server-rendered=true class="skeleton page">
 2     <div class=skeleton-nav></div>
 3     <div class=skeleton-swiper></div>
 4     <ul class=skeleton-tabs>
 5       <li class=skeleton-tabs-item><span></span></li>
 6       <li class=skeleton-tabs-item><span></span></li>
 7       <li class=skeleton-tabs-item><span></span></li>
 8       <li class=skeleton-tabs-item><span></span></li>
 9       <li class=skeleton-tabs-item><span></span></li>
10       <li class=skeleton-tabs-item><span></span></li>
11       <li class=skeleton-tabs-item><span></span></li>
12       <li class=skeleton-tabs-item><span></span></li>
13     </ul>
14     <div class=skeleton-banner></div>
15     <div class=skeleton-productions></div>
16     <div class=skeleton-productions></div>
17     <div class=skeleton-productions></div>
18     <div class=skeleton-productions></div>
19     <ul class=skeleton-tabs>
20       <li class=skeleton-tabs-item><span></span></li>
21       <li class=skeleton-tabs-item><span></span></li>
22       <li class=skeleton-tabs-item><span></span></li>
23       <li class=skeleton-tabs-item><span></span></li>
24       <li class=skeleton-tabs-item><span></span></li>
25       <li class=skeleton-tabs-item><span></span></li>
26       <li class=skeleton-tabs-item><span></span></li>
27       <li class=skeleton-tabs-item><span></span></li>
28     </ul>
29     <div class=skeleton-swiper></div>
30     <div class=skeleton-nav></div>
31   </div>

#③如果你是vue-cli脚手架搭的,直接就可以看到效果了,然后npm run build。就成了。

下图是我做的效果。

3.既然来到了这里,我们肯定要知道原理的。

  感谢作者的分享: 附上链接  https://segmentfault.com/a/1190000014832185

  原理:

  DOM里面有且仅有一个div#app,当js被执行完成之后,此div#app会被整个替换掉,也就是“测试测试测试测试测试测试测试测试”这部分内容,会被替换掉。

  所以:我们写在里面的html代码首屏时会显示,但DOM经过render渲染结束后,里面就被替换了。

       如下代码:是index.html里面代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>vue-skeleton</title>
  </head>
  <body>
    <div id="app">
      测试测试测试测试测试测试测试测试
    </div>
    <script src="/dist/build.js"></script>
  </body>
</html>    

4.如何从无到有些一个骨架屏

  ①通过vue-cli安装一个简易版的vue项目

vue init webpack-simple vue-skeleton

  ②安装第一次插件:

npm install vue-server-renderer --save
 //安装服务端渲染插件,利用它能够把.vue文件处理成html和css字符串的功能,来完成骨架屏的注入

npm install webpack-node-externals --save-dev
//安装外部插件,在项目中给css设置白名单
npm install html-webpack-plugin --save-dev  //打包的时候可以将index.html一起打包

  ③在/src目录下新建一个Skeleton.vue文件,样式都可以自己定义的,为了方便,可以直接复制粘贴。

 1 <template>
 2   <div class="skeleton page">
 3     <div class="skeleton-nav"></div>
 4     <div class="skeleton-swiper"></div>
 5     <ul class="skeleton-tabs">
 6       <li v-for="i in 8" class="skeleton-tabs-item"><span></span></li>
 7     </ul>
 8     <div class="skeleton-banner"></div>
 9     <div v-for="i in 4" class="skeleton-productions"></div>
10     <ul class="skeleton-tabs">
11       <li v-for="i in 8" class="skeleton-tabs-item"><span></span></li>
12     </ul>
13     <div class="skeleton-swiper"></div>
14     <div class="skeleton-nav"></div>
15   </div>
16 </template>
17
18 <style>
19   .skeleton {
20     position: fixed;
21     height: 100%;
22     overflow: hidden;
23     padding: 15px;
24     box-sizing: border-box;
25     background: #fff;
26     width: 98%;
27     top: 0;
28   }
29   .skeleton-nav {
30     height: 110px;
31     background: #eee;
32     margin-bottom: 15px;
33   }
34   .skeleton-swiper {
35     height: 440px;
36     background: #eee;
37     margin-bottom: 15px;
38   }
39   .skeleton-tabs {
40     list-style: none;
41     padding: 0;
42     margin: 0 -15px;
43     display: flex;
44     flex-wrap: wrap;
45   }
46   .skeleton-tabs-item {
47     width: 22%;
48     height: 80px;
49     box-sizing: border-box;
50     text-align: center;
51     margin-bottom: 15px;
52   }
53   .skeleton-tabs-item span {
54     display: inline-block;
55     width: 80px;
56     height: 80px;
57     border-radius: 55px;
58     background: #eee;
59   }
60   .skeleton-banner {
61     height: 250px;
62     background: #eee;
63     margin-bottom: 15px;
64   }
65   .skeleton-productions {
66     height: 50px;
67     margin-bottom: 15px;
68     background: #eee;
69   }
70 </style>

  ④在Skeleton.vue同个目录下,建立一个skeleton.entry.js入口文件

1 import Vue from ‘vue‘
2 import Skeleton from ‘./Skeleton.vue‘
3
4 export default new Vue({
5   components: {
6     Skeleton
7   },
8   template: ‘<skeleton />‘
9 })

  ⑤在根目录新建一个webpack.skeleton.conf.js文件,以专门用来进行骨架屏的构建,vue-server-renderer就是将Skeleton.vue生成json文件,以便插入到html。

    该配置文件和普通的配置文件基本完全一致,主要的区别在于其target: ‘node‘,配置了externals,以及在plugins里面加入了VueSSRServerPlugin。在VueSSRServerPlugin中,

指定了其输出的json文件名。我们可以通过运行下列指令,在/dist目录下生成一个skeleton.json文件

const path = require(‘path‘)
const webpack = require(‘webpack‘)
const nodeExternals = require(‘webpack-node-externals‘)
const VueSSRServerPlugin = require(‘vue-server-renderer/server-plugin‘)

var HtmlWebpackPlugin = require(‘html-webpack-plugin‘);
module.exports = { target: ‘node‘, entry: { skeleton: ‘./src/skeleton.entry.js‘ }, output: { path: path.resolve(__dirname, ‘./dist‘), publicPath: ‘/dist/‘, filename: ‘[name].js‘, libraryTarget: ‘commonjs2‘ },
plugins: [  new HtmlWebpackPlugin(    {      title: ‘test‘,      template: ‘index.html‘,    }  )],
module: { rules: [ { test: /\.css$/, use: [ ‘vue-style-loader‘, ‘css-loader‘ ] }, { test: /\.vue$/, loader: ‘vue-loader‘ } ] }, externals: nodeExternals({ whitelist: /\.css$/ }), resolve: { alias: { ‘vue$‘: ‘vue/dist/vue.esm.js‘ }, extensions: [‘*‘, ‘.js‘, ‘.vue‘, ‘.json‘] }, plugins: [ new VueSSRServerPlugin({ filename: ‘skeleton.json‘ }) ] }

  ⑥使用命令   将skeleton.vue文件变成json格式

webpack --config ./webpack.skeleton.conf.js 

  ⑦在根目录下新建一个skeleton.js,该文件即将被用于往index.html内插入骨架屏

 1 const fs = require(‘fs‘)
 2 const { resolve } = require(‘path‘)
 3
 4 const createBundleRenderer = require(‘vue-server-renderer‘).createBundleRenderer
 5
 6 // 读取`skeleton.json`,以`index.html`为模板写入内容
 7 const renderer = createBundleRenderer(resolve(__dirname, ‘./dist/skeleton.json‘), {
 8   template: fs.readFileSync(resolve(__dirname, ‘./index.html‘), ‘utf-8‘)
 9 })
10
11 // 把上一步模板完成的内容写入(替换)`index.html`
12 renderer.renderToString({}, (err, html) => {
13   fs.writeFileSync(‘index.html‘, html, ‘utf-8‘)
14 })

  ⑧将<!--vue-ssr-outlet-->占位符写在index.html里面,才能注入代码

<div id="app">
 <!--vue-ssr-outlet-->
</div>

  ⑨最后,只要运行node skeleton.js,就可以完成骨架屏的注入了。可以看下index.html的结果。

  ⑩进一步处理,把这些内容都压缩一下,改写skeleton.js

 

 1 ...
 2
 3 + const htmlMinifier = require(‘html-minifier‘)
 4
 5 ...
 6
 7 renderer.renderToString({}, (err, html) => {
 8 +  html = htmlMinifier.minify(html, {
 9 +    collapseWhitespace: true,
10 +    minifyCSS: true
11 +  })
12   fs.writeFileSync(‘index.html‘, html, ‘utf-8‘)
13 })

结果:

看不懂,可以再次参考原作者https://segmentfault.com/a/1190000014832185

  

  

原文地址:https://www.cnblogs.com/xiaoxiaossrs/p/9936516.html

时间: 2024-11-11 12:57:12

Vue页面显示骨架屏的相关文章

(尚043) Vue页面显示错误总结 `xxx`的区别

1. 错误原因: 修正页面显示: 原理解释: 在.vue文件中下面两种写法, 作用都是跳转到新的导航页,但是一种起效一种写法不起效,请问是什么原因???location.href = `${list.href}?index=${index}`location.href = '${list.href}?index=${index}'注意两个引号的不同 答:你第一个 `` 是es6的语法 用于拼接字符串的 里面的变量则用${xxx} 表示第二个用的话只能'xxx'+变量+'xxx' 用加号拼接 原文

自定义前端项目页面骨架屏

实际效果: 思路: 1.先根据页面编写骨架屏页面及样式 2.在最外层元素标签上添加“透明度动画”即可 3.根据实际业务逻辑控制显示/隐藏 代码如下: HTML部分 <!DOCTYPE html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale

小程序(uniapp)骨架屏应用

效果图 注意点: 1, 引入组建后, template 标签内加入<skeleton selector="skeleton" bgcolor="#FFF" v-if="showSkeleton"></skeleton> 其中 v-if="showSkeleton" 为显示骨架屏显示的参数. 2, data对象中设置showSkeleton: true // 默认一开始进入页面加载骨架屏内容. 骨架屏渲染

Vue项目骨架屏注入实践

相比于早些年前后端代码紧密耦合.后端工程师还得写前端代码的时代,如今已发展到前后端分离,这种开发方式大大提升了前后端项目的可维护性与开发效率,让前后端工程师关注于自己的主业.然而在带来便利的同时,也带来了一些弊端,比如首屏渲染时间(FCP)因为首屏需要请求更多内容,比原来多了更多HTTP的往返时间(RTT),这造成了白屏,如果白屏时间过长,用户体验会大打折扣,如果用户网速差,则FCP会更长. 由此引申出一系列的优化方法,骨架屏也因此被提出. FCP优化 在 Google 提出的以用户为中心的四个

Swift中使用presentViewController跳转页面后模拟器显示黑屏问题

Swift中使用presentViewController跳转页面后模拟器显示黑屏问题 问题原因 针对storyboard制作页面和手写页面,需要使用两种不同方法进行页面跳转. 解决办法 针对手写页面及storyboard制作页面,使用代码进行页面跳转的两种方法. 对于使用storyboard制作的页面 var sb = UIStoryboard(name: "Main", bundle:nil) var vc = sb.instantiateViewControllerWithIde

js控制页面的全屏展示和退出全屏显示

<!DOCTYPE html> <html> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <body > <button id="btn" >js控制页面的全屏展示和退出全屏显示</button> <div id="content" style="

解决Vue 使用vue-router切换页面时 页面显示没有在顶部的问题

有时候我们需要页面滚动条滚动到某一固定的位置,一般使用Window scrollTo() 方法. 语法就是:scrollTo(xpos,ypos) xpos:必需.要在窗口文档显示区左上角显示的文档的 x 坐标. ypos:必需.要在窗口文档显示区左上角显示的文档的 y 坐标. 例如滚动内容的坐标位置100,500: window.scrollTo(100,500); 解决办法: 在 Vue项目的main.js文件中加入以下代码即可解决: router.afterEach((to,from,ne

记录在ios系统上,自研app,灰度环境遇到的一个vue页面dom节点已渲染,但是显示部分空白的情况

一.问题产生背景: 在ios系统上,自研app,灰度环境,进入到前端页面后,从不同入口进入到适配车型页面,部分页面显示正常,部分页面显示异常,而适配车型页面的代码逻辑仅仅是请求接口,获取到数据后进行for循环渲染而已 1.vue页面代码如下: 2.js代码如下(请求数据,有缓存先取缓存,没有取接口请求返回数据,直接赋值): 3.接口返回数据如下: 4.除了ios.自研app.灰度环境的某个入口外,其他各端,包括ios.自研app.灰度环境的大部分入口(进到适配车型页)正常如下: 5.ios.自研

web性能优化之页面加载体验(骨架屏)

针对web页面的首屏加载问题,一直是个问题,为此还引出一个性能考量标准:白屏时间.首屏时间. 1.白屏时间 打开chrome控制台的Performance,我们可以看到页面的渲染快照: 这段白屏时间影响的因素归根结底就是:资源加载耗时较长(chunk.js文件下载耗时35.75s): 而对于现在的大行其道的SPA来说,只要这个js文件没有执行,那么页面的代码就只是这样: 自然渲染结果暂时就只是一个白板咯 2.首屏时间 通常首屏内容中加载最慢的就是图片或者 iframe 资源,因此可以理解为当图片