【问题标题】:Iterating & Rendering SVG in loop在循环中迭代和渲染 SVG
【发布时间】:2019-03-17 23:26:40
【问题描述】:

我用 react 做迭代图已经很长时间了,而且取得了很多成功。我唯一没有遇到的是通过迭代渲染 SVG。

从 react 组件开始设置迭代 mp 并从 ./data.js 导入数据数组。

Cards.js

import React from 'react';
import data from './data';

const icons = data.map(icon => (
  <>
   <div><span>{icon.svg}</span> {icon.type}</div>
  </>
));

const Cards = () => (<>{ icons }</>);

export default Cards;

数据数组...

data.js

export default[
 {
   svg: './icons/menu.svg',
   type: Menu
 },
{
   svg: './icons/home.svg',
   type: Home
 },
 {
   svg: './icons/clock.svg',
   type: History
 }
]

问题是,它无法渲染 .svg 以下目录,但最终会渲染字符串 ./icons/xxx.svg

我尝试了另一种方法..

svg: require('./icons/clock.svg'),

... 仍然得到相同的结果。我快没主意了。有什么建议?我了解require('') 使用 JSX img 标签...但是我只需要 .svg 文件,有没有办法将 svg 文件导入数据数组?

【问题讨论】:

  • 你试过这个
    {require(icon.svg)} {icon.type}

标签: javascript reactjs svg


【解决方案1】:

尝试这样设置:

import menu from './icons/menu.svg';
import home from './icons/home.svg';
import clock from './icons/clock.svg';

export default[
 {
   svg: menu,
   type: 'Menu'
 },
{
   svg: home,
   type: 'Home'
 },
 {
   svg: clock,
   type: 'History'
 }
]

并像这样实现它:

<div>
  <span>
    <img src={icon.svg} />
  </span> 
  {icon.type}
</div>

【讨论】:

  • @Ted 假设如果你有 100 个 svg 文件,那么?
【解决方案2】:

感谢你们花时间提供帮助...这些方法确实有效,给了我想法,我正在记下它。但这并不是我想要的,因为它必须使用&lt;img&gt; 标签,这不允许我调整大小、颜色等。我想避免在代码编辑器和插图程序之间来回切换。幸运的是,我找到了替代解决方案,它可能很乏味但很有效。这就是我所做的......

从创建 React PropTypes 组件开始..

图标.js

import React from 'react';
import PropTypes from 'prop-types';

const config = {
  svg: {
    display: 'flex-inline',
    margin: '0 auto'
  }
};

const Icons = props => (
  <svg
    style={config.svg}
    width={`${props.size}`}
    height={`${props.size}`}
    viewBox={`0 0 512 512`}
    className={props.className}
  >
    <path d={props.icon} />
  </svg>
);

Icons.propTypes = {
  icon: PropTypes.string.isRequired,
  size: PropTypes.number.isRequired,
  color: PropTypes.string,
  className: PropTypes.string.isRequired
};

Icons.defaultProps = {
  size: 32
};

创建另一个文件并包含具有已定义名称的 SVG 路径数组例如。菜单、主页、时钟

icons.js

export const SVGicon = {
  menu: /*Insert your SVG path here starting with 'M...*/, 

  home: /*Insert your SVG  path here starting with 'M...*/,

  clock: /*Insert your SVG path here starting with 'M...*/,

}

回到 data.js 并稍作修改(谢谢 Ted!)

data.js

import { SVGicon } from './icons'

export default[
  {
    svg: SVGicon.menu,
    type: 'Henu'
  },
  {
    svg: SVGicon.home,
    type: 'Home'
  },
  {
    svg: SVGicon.clock,
    type: 'History'
  }
]

返回 react 组件并稍作修改...

Cards.js

import React from 'react';
import data from './data';
import Icon from './Icon'; /* PropType Component */

const icons = data.map(icon => (
 <React.Fragment>
  <Icons icon={icon.svg} className="svg-icon" size={12} />
 </React.Fragment>
));

const Cards = () => (<React.Fragment>{ icons }</React.Fragment>);

export default Cards;

className="svg-icon"后面的css来调整颜色、效果等

main.scss

.svg-icon{
  fill: rgba(blue, .5);
  transition: fill .3s ease-out;
  &:hover{
    fill: rgba(red, 1);
 }

这应该显示不同的 SVG 图标数组,能够控制颜色、大小等...希望对您有所帮助

【讨论】:

  • 我正在尝试从公共文件夹中加载大约 50 个 svg,你能告诉我最好的方法是什么吗? @sirrius
  • 您能详细说明一下吗?我不确定我是否理解您所说的“公用文件夹中的 SVG”是什么意思?
  • 说我在 a.svg,2.svg,3.svg 等文件夹中有 50 个 svg 文件,我想在表格中显示这些 svg
  • 我了解,您想在不单独设置的情况下从公用文件夹中实现 50 .svg?如果是这样,请查看上面 ted 的答案。创建一个名为图标的文件夹或任何您喜欢的名称。将所有 50 个 .svg 放在文件夹内...导入所有 svg 并设置数组。这可能是最方便也是最好的方法。
【解决方案3】:

保持数据不变并使用 require 来呈现它

<div>
  <span>
    {require(icon.svg)}
  </span> 
  {icon.type}
</div>

【讨论】:

    【解决方案4】:

    我会将此作为评论添加到@sirrius,但没有足够的声誉:)

    我遵循了提供的解决方案,但我的图标不可见。这是因为视口仍然采用静态值,而不是宽度和高度的动态大小值。

    所以而不是:

    const Icons = props => (
      <svg
        style={config.svg}
        width={`${props.size}`}
        height={`${props.size}`}
        viewBox={`0 0 512 512`}
        className={props.className}
      >
        <path d={props.icon} />
      </svg>
    );
    

    无论大小道具如何,图标的 viewBox 高度和宽度都会为 512(想象在 512 viewBox 内有一个大小为 32 的 svg,它可能看起来不可见,因为尺寸不成比例) .

    你应该有:

    const Icons = props => (
      <svg
        style={config.svg}
        width={`${props.size}`}
        height={`${props.size}`}
        viewBox={`0 0 ${props.size} ${props.size}`}
        className={props.className}
      >
        <path d={props.icon} />
      </svg>
    );
    

    这会根据提供的大小调整 viewBox。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-26
      • 1970-01-01
      • 1970-01-01
      • 2021-02-22
      • 2013-04-28
      • 1970-01-01
      相关资源
      最近更新 更多