循环迭代和渲染SVG

时间:2018-10-12 17:32:50

标签: javascript reactjs svg

我从事反应的迭代映射已经很长时间了,并且取得了很多成功。我唯一没有遇到的就是通过迭代渲染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标签一起使用了。。。但是我只使用wanetd .svg文件,有没有办法将svg文件导入数据数组?

4 个答案:

答案 0 :(得分:3)

尝试像这样进行设置:

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>

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

谢谢你们花时间帮助...这些方法确实有效,给了我一些主意,我一直在注意。但这并不是我想要的,因为它必须使用<img>标签,这将不允许我调整大小,颜色等。我想避免在代码编辑器和插图程序之间来回移动。幸运的是,我找到了替代解决方案,这可能很乏味,但是可以用。这是我做的...

从创建React PropTypes组件开始。

Icon.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'
  }
]

返回以对组件进行反应并进行一些修改...

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图标,并具有控制颜色,大小等的功能。希望得到帮助

答案 3 :(得分:0)

我本来会将它添加为@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。