前端骨架屏的三种运用方式

319 阅读1分钟

一、骨架屏的三大运用方式及案例

  1. 静态HTML/CSS方案
<!-- 电商商品详情页案例 -->
<div class="skeleton-container">
  <div class="skeleton-header"></div>
  <div class="skeleton-gallery">
    <div class="skeleton-image"></div>
    <div class="skeleton-thumbnails">
      <div class="skeleton-thumb"></div>
      <div class="skeleton-thumb"></div>
    </div>
  </div>
  <div class="skeleton-content">
    <div class="skeleton-line" style="width:80%"></div>
    <div class="skeleton-line" style="width:60%"></div>
  </div>
</div>

<style>
.skeleton-image {
  background: linear-gradient(90deg,#f2f2f2 25%,#e6e6e6 50%,#f2f2f2 75%);
  animation: shimmer 1.5s infinite;
  height: 300px;
}
@keyframes shimmer {
  to { background-position-x: -200%; }
}
</style>

关键点:通过CSS动画模拟加载效果,需精确匹配真实DOM结构

  1. 组件化方案(Vue/React)
// Vue动态骨架屏组件
<template>
  <div v-if="loading" class="skeleton-wrapper">
    <SkeletonItem v-for="i in 5" :key="i" 
      :width="i===1 ? '80%' : '100%'" 
      :height="i===1 ? '24px' : '16px'"/>
  </div>
  <div v-else>
    <ActualContent :data="contentData"/>
  </div>
</template>

<script>
export default {
  components: {
    SkeletonItem: {
      props: ['width','height'],
      template: `<div class="skeleton-item" :style="{width, height}"/>`
    }
  }
}
</script>

优势:可复用组件,动态控制显示状态

  1. 自动化生成方案
// 使用vue-skeleton-webpack-plugin
const SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin');

module.exports = {
  configureWebpack: {
    plugins: [
      new SkeletonWebpackPlugin({
        webpackConfig: {
          entry: './src/skeleton.js'
        },
        minimize: true,
        quiet: true
      })
    ]
  }
}

特点:通过路由匹配自动生成对应骨架屏

二、关键实现要点

  1. 视觉一致性原则
  • 占位元素需与真实内容布局1:1对应
  • 使用与UI风格协调的渐变色系
  • 动画持续时间控制在1-1.5秒
  1. 性能优化策略
  • 骨架屏代码应控制在5KB以内
  • 避免使用图片资源,纯CSS实现
  • 与PWA的预缓存策略结合使用
  1. 状态管理规范
// 鸿蒙APP中的状态管理案例
Page({
  data: {
    loading: true,
    error: false,
    empty: false
  },
  onLoad() {
    fetchData().then(res => {
      this.setData({ 
        loading: false,
        list: res.data || []
      });
    }).catch(() => {
      this.setData({ error: true });
    });
  }
})

最佳实践:需处理加载失败/数据为空等边界情况