• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

React实现一个通用骨架屏组件示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

骨架屏是什么?

找到这里的同志,或多或少都对骨架屏有所了解,请容许我先啰嗦一句。骨架屏(Skeleton Screen)是一种优化用户弱网体验的方案,可以有效缓解用户等待的焦躁情绪。

Demo

先看个demo 大概了解下最终的产物及其使用方式

npm install obiusm-react-components
import { Skeleton } from 'obiusm-react-components';
  <Skeleton isVisible={true}>
    <div className="wrapper">
      <div className="content1"></div>
      <div data-skeleton-ignore={true}>123456</div>
      <div className="content2"></div>
      <div className="content3" data-skeleton-style={{ width: '50%' }}></div>
    </div>
  </Skeleton>

只需要在自己写的组件外面包一层决定其是否显示就可以了

设计思路

骨架可以在真实内容没有加载出来前让用户提前感知,可以提高用户体验 如果我们每次写组件的时候都要为其定制骨架,那就显得相当繁琐

得益于React props的这种数据数据传递方式,我们在props中可以轻松拿到整颗ReactElement的树。 那么我们只需要去递归遍历这个树从而去模仿其结构,复制其class就可以实现自动生成骨架了。

但在具体的使用上,我们可能只需要结构前几层的结构而不需要模拟整颗树的结构,也有可能自动生成的样式太丑我们需要定制其节点样式,还有可能我们不需要关注一些浮层类的内容或者说想忽略某一个节点

所以大概需要实现以下几个功能

  • 设定递归深度
  • 提供忽略节点的方法
  • 提供定制骨架节点样式的方法

具体实现

首先定义一个组件函数来决定是渲染骨架屏还是真实元素

function Skeleton(props: Props) {
  if (!props) {
    return <div />;
  }
  if (props.isVisible) {
    return createModal(props.children, props.depth || 4, 0);
  } else {
    return props.children ? props.children : <div />;
  }
}

createModal 对Skeleton下面包住的div进行递归遍历, 每次递归的时候将current+1并传递下去,这样我们可以判断已经递归了几层了 判断一下每个节点上data-skeleton-ignore是否有data-skeleton-style从而特殊处理就可以了

const createModal = (child: ReactElement, depth: number, current: number) => {
  if (
    depth === current ||
    (child && child.props && child.props['data-skeleton-ignore'])
  ) {
    return;
  }
  if (
    child &&
    child.props &&
    child.props.children &&
    Array.isArray(child.props.children) &&
    current < depth - 1
  ) {
    return (
      <div
        className={`${
          child.props.className !== undefined ? child.props.className : ''
        } ${'react-skeleton'}`}
        style={
          child.props && child.props['data-skeleton-style']
            ? child.props['data-skeleton-style']
            : {}
        }
        key={Math.random() * 1000}
      >
        {child.props.children && child.props.children.length > 0
          ? child.props.children.map((child: any) => {
              return createModal(child, depth, current + 1);
            })
          : '*'}
      </div>
    );
  } else {
    return (
      <div
        className={`${
          child.props && child.props.className ? child.props.className : ''
        } ${'react-skeleton2'}`}
        style={
          child.props && child.props['data-skeleton-style']
            ? child.props['data-skeleton-style']
            : {}
        }
        key={Math.random() * 1000}
      >
        *
      </div>
    );
  }
};

完整代码及其使用文档

完整代码 obiusm-react-components

文档 https://magic-zhu.github.io/obiusm-react-components-docs/components/skeleton/

到此这篇关于React实现一个通用骨架屏组件示例的文章就介绍到这了,更多相关React 骨架屏内容请搜索极客世界以前的文章或继续浏览下面的相关文章希望大家以后多多支持极客世界!


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
JavaScript递归详述发布时间:2022-02-05
下一篇:
VUE&nbsp;render函数使用和详解发布时间:2022-02-05
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap