Taro骨架屏组件

import Taro, { Component } from '@tarojs/taro'
import { View } from '@tarojs/components'
import './index.scss'
// 约定.skeleton样式类为骨架屏查找绘制节点的根节点
// 约定.skeleton-square样式类,表示绘制当前节点的骨架节点样式为方形(如商品卡片)
// 约定.skeleton-circular样式类,表示绘制当前节点的骨架节点为圆形(如logo)
// 约定.skeleton-cylinder样式类,表示绘制当前节点的骨架节点为长条形(如搜索框)
// 约定.skeleton-light与.skeleton-dark为块元素背景骨架样式
class ComponentCommonSkeleton extends Component {
  static defaultProps = {
    selector: 'skeleton',
    backgroundColor: '#fff',
    lightColor: 'white',
    darkColor: '#2f3333',
  }

  state = {
    lights: [],
    darks: [],
    squares: [],
    circulars: [],
    cylinders: [],
  }

  componentDidMount() {
    const { selector } = this.props

    Promise.all([
      this.selectAll(`.${selector} >>> .${selector}-light`),
      this.selectAll(`.${selector} >>> .${selector}-dark`),
      this.selectAll(`.${selector} >>> .${selector}-square`),
      this.selectAll(`.${selector} >>> .${selector}-circular`),
      this.selectAll(`.${selector} >>> .${selector}-cylinder`),
    ]).then(([lights, darks, squares, circulars, cylinders]) =>
      this.setState({
        lights,
        darks,
        squares,
        circulars,
        cylinders,
      }),
    )
  }

  selectAll = selector =>
    new Promise(resolve =>
      Taro.createSelectorQuery()
        .selectAll(selector)
        .boundingClientRect()
        .exec(res => resolve(res[0])),
    )

  createStyle = ({ width, height, top, left }) => ({
    width: `${width}px`,
    height: `${height}px`,
    top: `${top}px`,
    left: `${left}px`,
  })

  createCylinderStyle = rect => ({
    ...this.createStyle(rect),
    'border-radius': `${rect.height / 2}px`,
  })

  render() {
    const { backgroundColor, lightColor, darkColor } = this.props
    const { lights, darks, circulars, squares, cylinders } = this.state

    const skeletonStyle = { backgroundColor }

    return (
      <View
        className='skeleton'
        style={skeletonStyle}
      >
        {darks.map(dark => (
          <View
            key={`${dark.top}-${dark.left}`}
            className='item dark'
            style={{ ...this.createStyle(dark), backgroundColor: darkColor }}
          />
        ))}
        {lights.map(light => (
          <View
            key={`${light.top}-${light.left}`}
            className='item light'
            style={{ ...this.createStyle(light), backgroundColor: lightColor }}
          />
        ))}
        {squares.map(square => (
          <View
            key={`${square.top}-${square.left}`}
            className='item square'
            style={this.createStyle(square)}
          />
        ))}
        {circulars.map(circular => (
          <View
            key={`${circular.top}-${circular.left}`}
            className='item circular'
            style={this.createStyle(circular)}
          />
        ))}
        {cylinders.map(cylinder => (
          <View
            key={`${cylinder.top}-${cylinder.left}`}
            className='item cylinder'
            style={this.createCylinderStyle(cylinder)}
          />
        ))}
      </View>
    )
  }
}

export default  ComponentCommonSkeleton
$max-index: 1000;
$skeleton-index: $max-index - 3;
$skeleton-item-index: $skeleton-index + 2;
$skeleton-container-index: $skeleton-index + 1;
$grey-background-color: #f5f5f5;
$border-radius: 8px;
.skeleton {
  position: fixed;
  top: 0;
  left: 0;
  display: block;
  width: 100%;
  height: 100vh;
  z-index: 9997;
  overflow: hidden;

  .item {
    position: fixed;
    display: inline-block;
    background: $grey-background-color;
    z-index: $skeleton-item-index;

    &.dark,
    &.light {
      z-index: $skeleton-container-index;
    }

    &.square {
      border-radius: $border-radius;
    }

    &.circular {
      border-radius: 50%;
    }
  }
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值