定义
数据未加载前,将页面大致结构展现,直到数据返回,渲染页面补充进要显示的数据
用途
常用于文章列表,动态列表相对比较规则的页面
- 1.spa路由切换的loading,结合组件生命周期和ajax返回时机使用
- 2.首屏渲染的优化
- 3.微信小程序骨架屏
第一类
要自己要自己编写骨架屏,推荐两个成熟方便定制的svg组件定制为骨架屏的方案
- react-content-loader
- vue-content-loader
vue-content-loader
- 默认骨架
ContentLoader,
FacebookLoader,
CodeLoader,
BulletListLoader,
InstagramLoader,
ListLoader
- 支持自定义绘制链接
安装
npm install vue-content-loader --save
使用
import { ContentLoader } from 'vue-content-loader'
export default {
components: {
ContentLoader
}
}
<content-loader></content-loader>
第二类
首屏渲染(自动化方法)
page-skeleton-webpack-plugin
Page Skeleton 是一款 webpack 插件,该插件的目的是根据你项目中不同的路由页面生成相应的骨架屏页面,并将骨架屏页面通过 webpack 打包到对应的静态路由页面中。
该插件依赖于 html-webpack-plugin 使用vue-cli时内部已依赖不用单独配置
本文使用的是vue-cli + page-skeleton-webpack-plugin
- vue-cli 版本4.5.8
安装
//安装cli
sudo npm install -g @vue/cli
//查看版本
vue --version
//创建项目
vue create myapp
//配合vue-router使用
//常规安装vue-router || vue add router
//配置 路由
router.js
import Vue from "vue";
import Router from "vue-router";
import App from "./components/HelloWorld.vue";
import Search from "./components/search.vue";
Vue.use(Router);
export default new Router({
mode: "history",
routes: [
{
path: "/",
name: "home",
component: App,
},
{
path: "/search",
name: "search",
component: Search,
},
],
});
注意
这里选择history模式,想根据路由生成骨架屏,不能使用hash模式
main.js
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
Vue.config.productionTip = false;
new Vue({
render: (h) => h(App),
router,
}).$mount("#app");
App.vue
<template>
<div class="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
}
</script>
<style>
.app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
安装骨架屏插件
npm install --save-dev page-skeleton-webpack-plugin
过程中会去安装puppeteer,,比较慢,容易出错
安装成功后
根目录创建 vue.config.js
const { SkeletonPlugin } = require("page-skeleton-webpack-plugin");
const path = require("path");
module.exports = {
configureWebpack: {
plugins: [
new SkeletonPlugin({
pathname: path.resolve(__dirname, "./shell"), // 用来存储 shell 文件的地址
staticDir: path.resolve(__dirname, "./dist"), // 最好和 `output.path` 相同
routes: ["/", "/search"], // 将需要生成骨架屏的路由添加到数组中
}),
],
},
chainWebpack: (config) => {
// 解决vue-cli3脚手架创建的项目压缩html 干掉<!-- shell -->导致骨架屏不生效
console.log("------", process.env.NODE_ENV);
if (process.env.NODE_ENV !== "development") {
config.plugin("html").tap((opts) => {
opts[0].minify.removeComments = false;
return opts;
});
}
},
};
运行
npm run serve
这个过程可能会报错
可能是address already in use :::8989 at Server,修改成任何端口,依然提示端口被占用的bug。
解决方法
在node_modules/page-skeleton-webpack-plugin-master/src/skeletonPlugin.js 文件中修改
在SkeletonPlugin.prototype.createServer里加一个if判断
// const server = this.server = new Server(this.options) // eslint-disable-line no-multi-assign
// server.listen().catch(err => server.log.warn(err))
if (!this.server) {
const server = this.server = new Server(this.options) // eslint-disable-line no-multi-assign
server.listen().catch(err => server.log.warn(err))
}
运行成功会显示
在控制台输入toggleBar 或者 cmd+回车
然后点击那个control bar,生成骨架屏预览
这里可进行调整,通过routes切换路由
确认ok点击右上角保存【那个铅笔的icon】这时会在项目目录中生成shell文件-骨架屏文件
最后注入骨架屏
npm run build
注意
执行前在public/index.html中加入
<div id="app">
<!-- shell -->
</div>
ok,骨架屏就被打包注入到dist项目中了
目前官方demo还有很多坑,引入的时候还要多留意
【2】骨架屏生成工具
awesome-skeleton
基于node生成骨架屏 png 图片、base64 文本、html 文件
全局安装
npm i awesome-skeleton -g
局部安装
npm i awesome-skeleton -D
skeleton.config.json:
{
"pageName": "baidu",
"pageUrl": "https://www.baidu.com",
"openRepeatList": false,
"device": "iPhone X",
"minGrayBlockWidth": 80,
"minGrayPseudoWidth": 10,
"debug": true,
"debugTime": 3000,
"cookies": [
{
"domain": ".baidu.com",
"expirationDate": 1568267131.555328,
"hostOnly": false,
"httpOnly": false,
"name": "BDORZ",
"path": "/",
"sameSite": "unspecified",
"secure": false,
"session": false,
"storeId": "0",
"value": "yyyyyyyyy",
"id": 2
}
]
}
package.json
"scripts": {
"skeleton": "skeleton -c ./skeleton.config.json"
}
npm run skeleton
以demo baidu为例
小程序
小程序开发者工具提供了自动生成骨架屏代码的能力
位于模拟器右下角
点击后会在当前目录中生成
- page.skeleton.wxml
- page.skeleton.wxss
两个文件
通过template方式引入,通过if控制显示
/* pages/index/index.wxss 中引入样式 */
@import "index.skeleton.wxss";
<!-- pages/index/index.wxml 引入模板 -->
<import src="index.skeleton.wxml"/>
<template is="skeleton" wx-if="{{loading}}" data="{{}}"/>
骨架屏相关配置
可在 project.config.json 增加字段 skeleton-config 进行骨架屏相关配置,页面配置会覆盖掉全局配置。
还可进行区域拆分显示