Ant-design 源码分析之数据展示(一)Avatar

Ant-design 源码分析之数据展示(一)Avatar

2021SC@SDUSC

一、组件结构

1、ant代码结构

在这里插入图片描述

2、rc-ant代码结构

2.1、rc-util代码结构

在这里插入图片描述

2.2、rc-resize-observer代码结构

在这里插入图片描述

3、组件结构

在这里插入图片描述
ant中Avatar的index.tsx中引入了avatar和group

avatar中引用rc-resize-obsever做API。

二、antd组件调用关系

1、avatar.tsx
导入相应模块以及相应的ICON图标

import * as React from 'react';
import classNames from 'classnames';
import ResizeObserver from 'rc-resize-observer';
import { composeRef } from 'rc-util/lib/ref';
import { ConfigContext } from '../config-provider';
import devWarning from '../_util/devWarning';
import { Breakpoint, responsiveArray } from '../_util/responsiveObserve';
import useBreakpoint from '../grid/hooks/useBreakpoint';
import SizeContext, { AvatarSize } from './SizeContext';

创建了AvatarProps接口。
shape:指定头像的形状,有circle、square两种类型。
size:设置头像大小,有large、small、default、number( { xs: number, sm: number, …})类型。
gap:设置字符距离左右两侧边界单位像素,为number类型。
src:图片类头像的资源地址或者图片元素。为string或ReactNode类型。
srcSet:设置图片类头像响应式资源地址。是string类型。
darggable:设置图片是否允许拖动,为boolean类型。
icon:设置头像,为ReactNode类型。
style:使用css主题,为React.CSSProperties类型。
alt:设置图像无法显示时的替代文本。为string类型。
crossOrigin:CORS 属性设置。‘anonymous’ | ‘use-credentials’ | ‘’。
OnError:图片加载失败的事件,返回 false 会关闭组件默认的 fallback 行为。() => boolean。

export interface AvatarProps {
  /** Shape of avatar, options: `circle`, `square` */
  shape?: 'circle' | 'square';
  /*
   * Size of avatar, options: `large`, `small`, `default`
   * or a custom number size
   * */
  size?: AvatarSize;
  gap?: number;
  /** Src of image avatar */
  src?: React.ReactNode;
  /** Srcset of image avatar */
  srcSet?: string;
  draggable?: boolean;
  /** Icon to be used in avatar */
  icon?: React.ReactNode;
  style?: React.CSSProperties;
  prefixCls?: string;
  className?: string;
  children?: React.ReactNode;
  alt?: string;
  crossOrigin?: '' | 'anonymous' | 'use-credentials';
  /* callback when img load error */
  /* return false to prevent Avatar show default fallback behavior, then you can do fallback by your self */
  onError?: () => boolean;
}

setScaleParam:
当有子组件时,根据gap设定子组件大小。

const setScaleParam = () => {
    if (!avatarChildrenRef.current || !avatarNodeRef.current) {
      return;
    }
    const childrenWidth = avatarChildrenRef.current.offsetWidth; // offsetWidth avoid affecting be transform scale
    const nodeWidth = avatarNodeRef.current.offsetWidth;
    // denominator is 0 is no meaning
    if (childrenWidth !== 0 && nodeWidth !== 0) {
      const { gap = 4 } = props;
      if (gap * 2 < nodeWidth) {
        setScale(nodeWidth - gap * 2 < childrenWidth ? (nodeWidth - gap * 2) / childrenWidth : 1);
      }
    }
  };

handleImgLoadError:
判断图片是否加载失败。根据OnError()判断。

  const handleImgLoadError = () => {
    const { onError } = props;
    const errorFlag = onError ? onError() : undefined;
    if (errorFlag !== false) {
      setIsImgExist(false);
    }
  };

设置各项属性。

  const {
    prefixCls: customizePrefixCls,
    shape,
    size: customSize,
    src,
    srcSet,
    icon,
    className,
    alt,
    draggable,
    children,
    crossOrigin,
    ...others
  } = props;
const responsiveSizeStyle: React.CSSProperties = React.useMemo(() => {
    if (typeof size !== 'object') {
      return {};
    }

    const currentBreakpoint: Breakpoint = responsiveArray.find(screen => screens[screen])!;
    const currentSize = size[currentBreakpoint];

    return currentSize
      ? {
          width: currentSize,
          height: currentSize,
          lineHeight: `${currentSize}px`,
          fontSize: icon ? currentSize / 2 : 18,
        }
      : {};
  }, [screens, size]);

2、group.tsx
导入相应模块以及相应的ICON图标

import * as React from 'react';
import classNames from 'classnames';
import toArray from 'rc-util/lib/Children/toArray';
import { cloneElement } from '../_util/reactNode';
import { ConfigContext } from '../config-provider';
import Avatar from './avatar';
import Popover from '../popover';
import { AvatarSize, SizeContextProvider } from './SizeContext';

创建了GroupProps接口。

export interface GroupProps {
  className?: string;
  children?: React.ReactNode;
  style?: React.CSSProperties;
  prefixCls?: string;
  maxCount?: number;
  maxStyle?: React.CSSProperties;
  maxPopoverPlacement?: 'top' | 'bottom';
  /*
   * Size of avatar, options: `large`, `small`, `default`
   * or a custom number size
   * */
  size?: AvatarSize;
}

prefixCls:改变jsx文件里面的dom节点的className名称,string类型。
maxCount:显示的最大头像个数,number类型。
maxStyle:多余头像样式,CSSProperties类型。
maxPopoverPlacement:多余头像气泡弹出位置,top | bottom。
size:设置头像的大小,number | large | small | default | { xs: number, sm: number, …}类型。

通过接口实现了Group

const Group: React.FC<GroupProps> = props => {
  const { getPrefixCls, direction } = React.useContext(ConfigContext);
  const { prefixCls: customizePrefixCls, className = '', maxCount, maxStyle, size } = props;

  const prefixCls = getPrefixCls('avatar-group', customizePrefixCls);

  const cls = classNames(
    prefixCls,
    {
      [`${prefixCls}-rtl`]: direction === 'rtl',
    },
    className,
  );

  const { children, maxPopoverPlacement = 'top' } = props;
  const childrenWithProps = toArray(children).map((child, index) =>
    cloneElement(child, {
      key: `avatar-key-${index}`,
    }),
  );

  const numOfChildren = childrenWithProps.length;
  if (maxCount && maxCount < numOfChildren) {
    const childrenShow = childrenWithProps.slice(0, maxCount);
    const childrenHidden = childrenWithProps.slice(maxCount, numOfChildren);
    childrenShow.push(
      <Popover
        key="avatar-popover-key"
        content={childrenHidden}
        trigger="hover"
        placement={maxPopoverPlacement}
        overlayClassName={`${prefixCls}-popover`}
      >
        <Avatar style={maxStyle}>{`+${numOfChildren - maxCount}`}</Avatar>
      </Popover>,
    );
    return (
      <SizeContextProvider size={size}>
        <div className={cls} style={props.style}>
          {childrenShow}
        </div>
      </SizeContextProvider>
    );
  }

  return (
    <SizeContextProvider size={size}>
      <div className={cls} style={props.style}>
        {childrenWithProps}
      </div>
    </SizeContextProvider>
  );
};

三、rc-antd组件调用关系

1、Rc-resize-observer

Rc-resize-observer:

生命周期方法:
componentDidMount()
请求数据,一般用在进入页面后,数据初始化。在第一次渲染后调用,只在客户端。之后	组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你	想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval
或者发送AJAX请求等操作(防止异步操作阻塞UI)。
componentDidUpdate()
在组件完成更新后立即调用。在初始化时不会被调用。
一般的情况是管理第三个的UI组件,以及和本地UI元素交互。
componentWillUnmount()
在渲染前调用,在客户端也在服务端。
onComponentUpdated()
当禁用或元素改变时,取消注册,调用onResize()方法,传递元素element。
onResize()
会在窗口或框架被调整大小时发生。动态调整窗口大小。
destroyObserver()
关闭观察者。
render()
渲染。

2、Rc-util
待更新。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Ant Design 的 Table 中显示图片,可以使用 `render` 函数来渲染每一行的数据,并在其中添加 `img` 标签来显示图片。具体步骤如下: 1. 在 Table 中,使用 `render` 函数来渲染每一行的数据,其中包括需要显示图片的列。 2. 在 `render` 函数中,使用 `img` 标签来显示图片。可以使用 `record` 参数来获取当前行的数据,并从中获取图片的链接。 下面是一个简单的示例代码: ```vue <template> <a-table :columns="columns" :data-source="data" /> </template> <script> export default { data() { return { data: [ { name: "John Brown", age: 32, avatarUrl: "https://example.com/avatar.jpg", }, { name: "Jim Green", age: 42, avatarUrl: "https://example.com/avatar.jpg", }, ], }; }, computed: { columns() { return [ { title: "Name", dataIndex: "name", }, { title: "Age", dataIndex: "age", }, { title: "Avatar", dataIndex: "avatarUrl", scopedSlots: { customRender: "avatar" }, }, ]; }, }, methods: { renderAvatar(url) { return <img src={url} style="width: 50px" />; }, }, }; </script> ``` 在这个示例中,我们使用 `render` 函数来渲染每一行的数据,并在其中添加 `img` 标签来显示图片。在 `columns` 中,我们将 `avatarUrl` 列的 `scopedSlots` 属性设置为 `customRender: 'avatar'`,表示使用名为 `avatar` 的 `slot` 来渲染这一列。在 `methods` 中,我们定义了一个名为 `renderAvatar` 的函数,用于渲染图片。最终,我们将 `renderAvatar` 函数作为 `avatar` `slot` 的内容,从而显示图片。 希望这可以帮助到你!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值