骨架屏

定义

数据未加载前,将页面大致结构展现,直到数据返回,渲染页面补充进要显示的数据

用途

常用于文章列表,动态列表相对比较规则的页面

  • 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))
}

其他问题 - 官方demo采坑史

运行成功会显示


image.png

在控制台输入toggleBar 或者 cmd+回车


image.png

然后点击那个control bar,生成骨架屏预览


image.png

这里可进行调整,通过routes切换路由


image.png

确认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为例

image.png

image.png

小程序

小程序开发者工具提供了自动生成骨架屏代码的能力

image.png

位于模拟器右下角
点击后会在当前目录中生成

  • 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 进行骨架屏相关配置,页面配置会覆盖掉全局配置。

还可进行区域拆分显示

传送门

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。