美文网首页
定制修改组件库的几种方式

定制修改组件库的几种方式

作者: VioletJack | 来源:发表于2021-02-09 14:20 被阅读0次

    在前端开发中,使用组件库是必然的。然而有些组件库的样式、功能无法满足需求时应该如何修改呢。下面是我用到的几种方式。本文以 React 和 ant-design 为例(Vue 也有类似的机制)。

    1. 定制主题

    很多组件库自身就支持定制主题,这种情况适合于有明确组件设计规范的项目使用。下面是一些定制主题的文档:

    2. 使用 css-modules 重写组件样式

    当 React 项目使用了 css-modules,可以在 component 级别覆盖组件库的样式。比如使用了 antd 的组件,但是组件的样式与设计稿的样式有些许出入,既可以通过 CSS modules 的 global 来进行样式覆盖。

    .confirmStyle {
      width: 460px;
    
      :global {
        .ant-modal-body {
          padding: 24px 27px 23px;
        }
    
        .ant-modal-confirm-title {
          margin-top: 8px;
        }
    
        .ant-modal-confirm-btns {
          margin-top: 40px;
        }
    
        .ant-modal-confirm-btns {
          > button {
            width: 72px;
            height: 36px;
            border-radius: 4px;
          }
    
          > button:nth-of-type(1) {
            margin-right: 10px;
          }
        }
      }
    }
    

    如果样式覆盖顺序没有生效,可以加上 !important

       .ant-modal-body {
          padding: 24px 27px 23px !important;
        }
    

    3. 对组件进行二次封装

    一般组件都会留有 API 来自定义一些东西。比如容器样式、关闭按钮、内部组件样式、图标替换等。如果这个组件被应用到一个地方,直接在组件 API 上定义改动即可。如果这个组件会被反复使用。就可以进行组件的二次封装。

    下面我基于 antd 的 Modal 组件的二次封装,整个项目都改用封装后的 Modal 组件。

    import React from 'react'
    import { Modal } from 'antd'
    import { ModalFuncProps, ModalProps } from 'antd/lib/modal'
    import CloseIcon from '@/assets/close.svg'
    import WarningIcon from '@/assets/confirm-warning.svg'
    import InfoSvg from '@/assets/confirm-info.svg'
    import ErrorSvg from '@/assets/confirm-error.svg'
    import styles from './index.scss'
    
    interface Props {
      children: any
    }
    
    const renderCloseIcon = <CloseIcon button className={styles.closeIcon} fill='#8c8c8c' />
    
    const CustomModal =  (props: ModalProps & Props) => {
      return (
        <Modal closeIcon={renderCloseIcon} centered {...props}>
          {props.children}
        </Modal>
      )
    }
    
    CustomModal.info = (props: ModalFuncProps) => {
      return Modal.info({
        closeIcon: renderCloseIcon,
        ...props,
      })
    }
    
    CustomModal.success = (props: ModalFuncProps) => {
      return Modal.success({
        closeIcon: renderCloseIcon,
        ...props,
      })
    }
    
    CustomModal.error = (props: ModalFuncProps) => {
      return Modal.error({
        closeIcon: renderCloseIcon,
        ...props,
      })
    }
    
    CustomModal.warn = (props: ModalFuncProps) => {
      return Modal.warn({
        closeIcon: renderCloseIcon,
        ...props,
      })
    }
    
    CustomModal.warning = (props: ModalFuncProps) => {
      return Modal.warning({
        closeIcon: renderCloseIcon,
        ...props,
      })
    }
    
    const ICON_SIZE: number = 44
    const WIDTH: number = 460
    
    // 将之前的全局 modal 逻辑合并到一起
    CustomModal.confirm = (props: ModalFuncProps) => {
      let { type } = props
      if (!type) type = 'warning'
    
      const typeMap: { [key: string]: { className: string; icon: React.ReactNode } } = {
        warning: {
          className: styles.confirmTypeIsWarning,
          icon: <WarningIcon style={{ width: ICON_SIZE, height: ICON_SIZE }} />
        },
        info: {
          className: styles.confirmTypeIsInfo,
          icon: <InfoSvg style={{ width: ICON_SIZE, height: ICON_SIZE }} />
        },
        error: {
          className: styles.confirmTypeIsError,
          icon: <ErrorSvg style={{ width: ICON_SIZE, height: ICON_SIZE }} />
        }
      }
    
      return Modal.confirm({
        icon: typeMap[type as string].icon,
        className: typeMap[type as string].className,
        width: WIDTH,
        okText: '确认',
        cancelText: '取消',
        closeIcon: renderCloseIcon,
        ...props
      })
    }
    
    const { destroyAll, useModal, config } = Modal
    
    CustomModal.destroyAll = destroyAll
    CustomModal.useModal = useModal
    CustomModal.config = config
    
    export default CustomModal
    

    4. fork 组件库进行修改和同步维护

    之前遇到一个需要需要将表格多选功能改为鼠标 hover 的时候显示 checkbox 而非 hover 情况下显示为数字序号。这个需求在我们用到的 ali-react-table 中并没有相关 API 实现。
    既然无法实现需求,就放弃用这个库吗?非也!可以通过将项目 fork 下来,修改源码来实现。且如果这个库有后续的更新,也可以将主仓库的改动合并到 fork 的仓库中。
    而在 package.json 的引用中,改为引用 fork 下来的项目即可。这里的引用可以直接引用 git 路径,也可以发到 npm 上去引用。

    最后

    或许还有别的重写组件的方法,但目前来看以上四种方法都是比较优雅的。

    相关文章

      网友评论

          本文标题:定制修改组件库的几种方式

          本文链接:https://www.haomeiwen.com/subject/kbwqxltx.html