在使用 Native APP 时我们经常可以看到在实际内容加载出来之前会有一些 占位图片,因为其结构和实际加载内容相似(如新闻页面加载之前也会有一个纵向列表),因此让用户感知到自己的页面正在加载中,体验较好。而传统的 Web 站点因为无法实现这一点,在加载前统一为白屏,我们能优化的仅仅是缩短这个 白屏时间,这就决定了 Web App 相较于 Native APP 在用户体验上的先天劣势。

我们把这个 占位图片 称为 skeleton 。通过 PWA 的缓存机制,我们现在已经有能力让 Skeleton 也出现在 Web App 上取代白屏。在了解具体细节之前,我们先观察一下我的demo效果图。

github地址:https://github.com/hwq888/skeleton

我们希望在构建时渲染 skeleton 组件,将渲染 DOM 插入 html 的挂载点中,同时将使用的样式通过 style 标签内联。这样在前端 JS 渲染完成之前,用户将看到页面的大致骨架,感知到页面是正在加载的。

我们当然可以选择在开发时直接将页面骨架内容写入 html 模版中,但是这会带来两个问题:

  1. 开发 skeleton 与其他组件体验不一致。
  2. 多页应用中多个页面可能共用同一个 html 模版,而又有独立的 skeleton。

下面我们将看看插件在具体实现中是如何解决这两个问题的:

vue-skeleton-webpack-plugin

github 地址:https://github.com/lavas-project/vue-skeleton-webpack-plugin

具体实现步骤:

1、我们用vue-cli 直接构建一下项目跑起来(具体怎么构建就不说了)

2、进去当前项目,执行命令 : npm install vue-skeleton-webpack-plugin

3、我们在src目录下创建 Skeleton.vue

<template><div class="skeleton-wrapper"><header class="skeleton-header"></header><section class="skeleton-block"><img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMTA4MCAyNjEiPjxkZWZzPjxwYXRoIGlkPSJiIiBkPSJNMCAwaDEwODB2MjYwSDB6Ii8+PGZpbHRlciBpZD0iYSIgd2lkdGg9IjIwMCUiIGhlaWdodD0iMjAwJSIgeD0iLTUwJSIgeT0iLTUwJSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94Ij48ZmVPZmZzZXQgZHk9Ii0xIiBpbj0iU291cmNlQWxwaGEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0T3V0ZXIxIi8+PGZlQ29sb3JNYXRyaXggaW49InNoYWRvd09mZnNldE91dGVyMSIgdmFsdWVzPSIwIDAgMCAwIDAuOTMzMzMzMzMzIDAgMCAwIDAgMC45MzMzMzMzMzMgMCAwIDAgMCAwLjkzMzMzMzMzMyAwIDAgMCAxIDAiLz48L2ZpbHRlcj48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDEpIj48dXNlIGZpbGw9IiMwMDAiIGZpbHRlcj0idXJsKCNhKSIgeGxpbms6aHJlZj0iI2IiLz48dXNlIGZpbGw9IiNGRkYiIHhsaW5rOmhyZWY9IiNiIi8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCA0NGg1MzN2NDZIMjMweiIvPjxyZWN0IHdpZHRoPSIxNzIiIGhlaWdodD0iMTcyIiB4PSIzMCIgeT0iNDQiIGZpbGw9IiNGNkY2RjYiIHJ4PSI0Ii8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCAxMThoMzY5djMwSDIzMHpNMjMwIDE4MmgzMjN2MzBIMjMwek04MTIgMTE1aDIzOHYzOUg4MTJ6TTgwOCAxODRoMjQydjMwSDgwOHpNOTE3IDQ4aDEzM3YzN0g5MTd6Ii8+PC9nPjwvc3ZnPg=="><img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMTA4MCAyNjEiPjxkZWZzPjxwYXRoIGlkPSJiIiBkPSJNMCAwaDEwODB2MjYwSDB6Ii8+PGZpbHRlciBpZD0iYSIgd2lkdGg9IjIwMCUiIGhlaWdodD0iMjAwJSIgeD0iLTUwJSIgeT0iLTUwJSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94Ij48ZmVPZmZzZXQgZHk9Ii0xIiBpbj0iU291cmNlQWxwaGEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0T3V0ZXIxIi8+PGZlQ29sb3JNYXRyaXggaW49InNoYWRvd09mZnNldE91dGVyMSIgdmFsdWVzPSIwIDAgMCAwIDAuOTMzMzMzMzMzIDAgMCAwIDAgMC45MzMzMzMzMzMgMCAwIDAgMCAwLjkzMzMzMzMzMyAwIDAgMCAxIDAiLz48L2ZpbHRlcj48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDEpIj48dXNlIGZpbGw9IiMwMDAiIGZpbHRlcj0idXJsKCNhKSIgeGxpbms6aHJlZj0iI2IiLz48dXNlIGZpbGw9IiNGRkYiIHhsaW5rOmhyZWY9IiNiIi8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCA0NGg1MzN2NDZIMjMweiIvPjxyZWN0IHdpZHRoPSIxNzIiIGhlaWdodD0iMTcyIiB4PSIzMCIgeT0iNDQiIGZpbGw9IiNGNkY2RjYiIHJ4PSI0Ii8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCAxMThoMzY5djMwSDIzMHpNMjMwIDE4MmgzMjN2MzBIMjMwek04MTIgMTE1aDIzOHYzOUg4MTJ6TTgwOCAxODRoMjQydjMwSDgwOHpNOTE3IDQ4aDEzM3YzN0g5MTd6Ii8+PC9nPjwvc3ZnPg=="></section></div>
</template><script>export default {name: 'skeleton'}
</script><style scoped>.skeleton-header {height: 40px;background: #1976d2;padding:0;margin: 0;width: 100%;}.skeleton-block {display: flex;flex-direction: column;padding-top: 8px;}</style>

4、创建入口文件:entry-skeleton.js

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

5、我们在build 目录下创建 webpack.skeleton.conf.js

'use strict';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/entry-skeleton.js')},output: Object.assign({}, baseWebpackConfig.output, {libraryTarget: 'commonjs2'}),externals: nodeExternals({whitelist: /\.css$/}),plugins: []
})

然后在webpack.dev.conf.js和webpack.prod.conf.js分别加入

const SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin')
// inject skeleton content(DOM & CSS) into HTMLnew SkeletonWebpackPlugin({webpackConfig: require('./webpack.skeleton.conf'),quiet: true})

然后就完成了。

延伸:

1、vue-skeleton-webpack-plugin 可以 使用多个 骨架屏 ,具体的可以查看官网地址:https://github.com/lavas-project/vue-skeleton-webpack-plugin

2、Skeleton Screen 样式实现

第一种

简单堆砌出元素结构

html

<div class="skeleton"><div class="skeleton-head"></div><div class="skeleton-body"><div class="skeleton-title"></div><div class="skeleton-content"></div></div>
</div>

css

.skeleton {padding: 10px;
}.skeleton .skeleton-head,
.skeleton .skeleton-title,
.skeleton .skeleton-content {background: rgb(194, 207, 214);
}.skeleton-head {width: 100px;height: 100px;float: left;
}.skeleton-body {margin-left: 110px;
}.skeleton-title {width: 500px;height: 60px;
}.skeleton-content {width: 260px;height: 30px;margin-top: 10px;
}    

第二种

背景动画,html结构相同,修改部分css样式

.skeleton .skeleton-head,
.skeleton .skeleton-title,
.skeleton .skeleton-content {background: rgb(194, 207, 214);background-image: linear-gradient(90deg,rgba(255, 255, 255, 0.15) 25%, transparent 25%);background-size: 20rem 20rem;animation: skeleton-stripes 1s linear infinite;
}@keyframes skeleton-stripes {from {background-position: 0 0 ;}to {background-position: 20rem 0;}
}

第三种

元素结构长度变化 

.skeleton {padding: 10px;
}.skeleton .skeleton-head,
.skeleton .skeleton-title,
.skeleton .skeleton-content {background: rgb(194, 207, 214);
}.skeleton-head {width: 100px;height: 100px;float: left;
}.skeleton-body {margin-left: 110px;
}.skeleton-title {width: 500px;height: 60px;transform-origin: left;animation: skeleton-stretch .5s linear infinite alternate;
}.skeleton-content {width: 260px;height: 30px;margin-top: 10px;transform-origin: left;animation: skeleton-stretch .5s -.3s linear infinite alternate;
}@keyframes skeleton-stretch {from {transform: scalex(1);}to {transform: scalex(.3);}
}

vue-cli 构建的项目如何加入骨架屏 skeleton相关推荐

  1. Vue CLI构建SPA项目教你手把手创建SPA项目

    下载安装Vue-CLI 官方文档:https://cli.vuejs.org/zh/ 首先要确定自己的电脑上安装了 Node.js 8.9 或更高版本. 然后,我们就可以使用 npm 来安装 vue/ ...

  2. cli vue 外部js 引入 文件_javascript - vue cli构建的项目中,vue组件里怎么引入外部js文件里的方法...

    问 题 我想在content组件里调用外部js(test.js)里的diyfun方法,怎么实现呢? 我的content组件代码: Click export default { data () { re ...

  3. vue = 什么意思_记录使用@vue/cli搭建Vue3项目完整流程

    最近发现vue两大UI框架Element UI和Ant Design Vue都已经支持Vue3了,如果再不学习Vue3就落伍了,此文章记录下使用@vue/cli搭建Vue3项目完整流程. 1 安装vu ...

  4. cli vue 卸载_记录使用@vue/cli搭建Vue3项目完整流程

    最近发现vue两大UI框架Element UI和Ant Design Vue都已经支持Vue3了,如果再不学习Vue3就落伍了,此文章记录下使用@vue/cli搭建Vue3项目完整流程. 1 安装vu ...

  5. Android中骨架屏(Skeleton Screen)使用

    Android中骨架屏(Skeleton Screen)使用 1.什么是骨架屏 页面在没有完全渲染完成之前,用户会看到一个占位的样式,用以描绘了当前页面的大致框架,加载完成后,最终骨架屏中各个占位部分 ...

  6. vue CLI脚手架搭项目

    1.安装 node.js环境 官网下载:https://nodejs.org/en/download/ 一直默认就行,路径可以改变但要记得到 安装完成后cmd打开终端,输入node -v ,npm - ...

  7. 通过Vue CLI 4创建项目

    1.安装Vue CLI 4 前提是你已经安装了Node(自带npm),Node版本要求:Vue CLI 4.x 需要 Node.js v8.9 或更高版本 (推荐 v10 以上). Vue CLI 的 ...

  8. Vue CLI脚手架新建项目

    Windows PowerShell 版权所有(C) Microsoft Corporation.保留所有权利.安装最新的 PowerShell,了解新功能和改进!https://aka.ms/PSW ...

  9. #周分享#骨架屏[Skeleton Screen]

    什么是骨架屏 骨架屏就是在页面数据尚未加载前先给用户展示出页面的大致结构,直到请求数据返回后再渲染页面,补充进需要显示的数据内容.常用于文章列表.动态列表页等相对比较规则的列表页面 是进度条和菊花圈的 ...

最新文章

  1. vim自定义配置之autoComplPop设置
  2. 图解Win7下安装Borland C++ 3.1失败记
  3. mysql通用查询日志_MySQL通用查询日志(GeneralQueryLog)_MySQL
  4. ExtJs 实现动态列,动态多表头 在这里添加日志标题
  5. 4.5丢弃法 drop out
  6. html三元运算符 模板,AngularJS模板中的三元运算符
  7. python闭包与装饰器的代码解释
  8. 进行数据清洗_[经验漫谈]使用Python进行数据表格清洗和分析
  9. CentOS下rsync数据同步备份
  10. EF的注解Annotation和Fluent API
  11. python怎么配置pip_python如何配置pip
  12. linux plc编程软件安装,西门子PLC编程软件S7-200 v4.0.8官方版
  13. 计算机教室布线施工方案,最新计算机教室施工方案.docx
  14. 用ESP32打造一个物联网红外测温打卡机/春节结束急着上班?哒咩,再努力奋斗也要先测体温
  15. 人工智能机器人技术概述
  16. 部署 php 项目,使用deployer 来部署PHP项目
  17. 阿里云部署SVN服务器
  18. pdf转换成word转换器在线使用效果
  19. 20年美赛C题数据集解读与O奖论文思路
  20. OpenCV-Python人脸识别,车辆识别,自定义物体识别,自定义分类器

热门文章

  1. 好玩的==百度java面试题
  2. 【个人感悟】暑期总结与感想
  3. 字节内部标配的鼠标垫火遍了编程圈,我粉丝每人包邮送1块!
  4. 阿里巴巴开源的免费数据库工具Chat2DB
  5. spring packagesToScan无法扫描到jar中类的解决办法
  6. Android 手机存储文件各种路径
  7. Task 3 --字典、元组、布尔类型、读写文件课后练习及补充
  8. ADB、Charles Win10系统 64位下载包
  9. 母子页的iframe传参跳转,参数需要编码
  10. 俄罗斯四大运营商与Yota签署LTE共享和谈