reactjs 使用Next.js导入动态英雄图标

fykwrbwg  于 2023-05-28  发布在  React
关注(0)|答案(2)|浏览(113)

我在Next.js项目中使用了heroicons,由于它目前不支持动态导入(通过将图标名称传递给组件),我创建了自己的组件。

// HeroIcon.tsx
import * as SolidIcons from '@heroicons/react/solid';
import * as OutlineIcons from '@heroicons/react/outline';

interface Props {
  icon: string;
  color?: string;
  size?: number;
  outline?: boolean;
}

export const HeroIcon = (props: Props): JSX.Element => {
  const { icon, color, size, outline = false } = props;

  const { ...icons } = outline ? OutlineIcons : SolidIcons;

  // @ts-ignore
  const Icon: JSX.Element = icons[icon];

  const classes = [
    `${color ? color : 'text-black'}`,
    `h-${size ? size : 6}`,
    `w-${size ? size : 6}`
  ];

  return (
    // @ts-ignore
    <Icon className={classes.join(' ')} />
  );
};

我以后可以这样使用它:

<HeroIcon icon='CogIcon' color='text-blue-600' size={6} outline />

当它在我的开发服务器上工作时:

当我用npm run build构建项目并用npm start启动它时,我得到的结果是:

而在移动的设备上,图标根本不可见。
该页面使用SSG预渲染,并使用getStaticPathsgetStaticProps
”””任何想法可能是什么原因?**

tyky79it

tyky79it1#

这段代码就是问题所在

const classes = [
    `${color ? color : 'text-black'}`,
    `h-${size ? size : 6}`,
    `w-${size ? size : 6}`
  ];

如果你想动态地改变Tailwind CSS样式,你可以这样写代码。

const classes = [
    `${color ? color : 'text-black'}`,
    size ? 'h-12' : 'h-6',
    size ? 'w-12' : 'w-6',
  ];

这是由于Purge CSS的工作方式,Tailwind CSS使用Purge CSS来优化Tailwind CSS类以用于生产。
遗憾的是,你不能像h-{x}一样编写类,因为Tailwind CSS在构建时被清除,h-{x}不会评估为有效的Tailwind CSS类。

参考资料

https://v2.tailwindcss.com/docs/optimizing-for-production#writing-purgeable-html

k5hmc34c

k5hmc34c2#

扩展@brandon-julio-thenaro的答案,这里是使用tailwind-merge库实现的另一种很酷的方法:

// HeroIcon.tsx
import * as SolidIcons from '@heroicons/react/24/solid';
import * as OutlineIcons from '@heroicons/react/24/outline';
import { twMerge } from 'tailwind-merge';

enum IconType {
  outline = 'outline',
  solid = 'solid',
}

interface DynamicHeroIconProps {
  icon: string;
  type?: IconType;
  className?: string;
}

export const DynamicHeroIcon = (props: DynamicHeroIconProps): JSX.Element => {
  const { icon, className, type = 'outline' } = props;

  const { ...icons } = type === 'outline' ? OutlineIcons : SolidIcons;

  // @ts-ignore
  const Icon: JSX.Element = icons[icon];

  const c = twMerge('h-6 w-6 text-black', className);

  return (
    // @ts-ignore
    <Icon className={c} />
  );
};

这种方式允许您满足PurgeCSS需求,同时保持组件广泛可重写。

相关问题