如何将样式应用于 SVG 元素数组
How to apply style to an array of SVG elements
我有一组 .svg
个图标,其中每个图标都有一些我需要覆盖的属性:
<svg width="24" height="24" viewBox="0 0 24 24"> ... </svg>
import styled from 'styled-components';
import Github from 'assets/github.svg';
import Facebook from 'assets/facebook.svg';
import Twitter from 'assets/twitter.svg';
...
const icons = [
<Github />,
<Facebook />,
<Twitter />,
...
];
我想为每个图标应用相同的样式而不需要重复代码并使用CSS-in-JS
。
目前我的解决方案存在一些问题:
// Works but,
// I want to use CSS-in-JS like styled-components
// for easier maintenance
const iconStyle = {
width: 50,
height: 50
};
const SocialBar = () => (
<IconBar as={FlexBox}>
{icons.map((icon, key) => (
<div key={key}>{React.cloneElement(icon, iconStyle)}</div>
))}
</IconBar>
);
// Works but,
// there are too many icons
const SocialBar = () => (
<IconBar as={FlexBox}>
<Github style={iconStyle} />
<Facebook style={iconStyle} />
...
</IconBar>
);
这样的 svg
组件样式将不起作用:
// Won't override the width="24" height="24" properties
const StyledIcon = styled(Github)`
width: 50;
height: 50;
`;
这是一种方法。
//Github.js
import React from "react";
export default function Github({height, width}) {
return (
<svg width={width} height={height} viewBox="0 0 24 24"> ... </svg>
);
}
然后你想在哪里使用它。
<Github height={24} width={24} />
相对于您已有的代码示例,我不完全确定您的要求是什么。您是否试图避免使用 React.cloneElement
?将图标数组作为函数,而不是 jsx 元素。 map
将其应用于 jsx 版本并将样式应用于每个
const icons = [
Github,
Facebook,
Twitter,
]
buildIcons() {
const style = {
//..
}
return icons.map((icon, idx) => (
<icon style={style} key={idx}/>
))
}
使用索引作为键是可行的,但如果你能找到每个图标唯一的不同属性,那就更好了。
您可以用一个元素(如 i
)包裹 SVG,并使用 styled-component 中定义的一些 CSS 为其中的任何 svg
子元素设置样式(您也可以定位 g
和 path
)。不幸的是,SVG 使用起来非常棘手,因此您 可能 需要手动 copy/paste 将 SVG xml 放入 JS 文件中(如果您使用 CRA, you can import a ReactComponent from an SVG).
工作示例(copy/pasted SVG 到 JS 文件——第一个示例是默认的,第二个示例传入 props,第三个示例传入多个 props):
Icon/Icon.js(此组件接受样式化组件生成的 className
和任何放置在其中的 children
)
import React from "react";
import PropTypes from "prop-types";
const Icon = ({ className, children }) => (
<i className={className}>{children}</i>
);
Icon.propTypes = {
className: PropTypes.string.isRequired,
children: PropTypes.node.isRequired
};
export default Icon;
Icon/index.js(这将为上面的 Icon
组件设置样式;随后它将设置 children
的样式)
import styled from "styled-components";
import Icon from "./Icon";
const StyledIcon = styled(Icon)`
margin: 0 20px;
svg {
fill: ${({ fill }) => fill || "#03a9f3"};
height: ${({ dimension }) => dimension || "50px"};
width: ${({ dimension }) => dimension || "50px"};
}
`;
export default StyledIcon;
我有一组 .svg
个图标,其中每个图标都有一些我需要覆盖的属性:
<svg width="24" height="24" viewBox="0 0 24 24"> ... </svg>
import styled from 'styled-components';
import Github from 'assets/github.svg';
import Facebook from 'assets/facebook.svg';
import Twitter from 'assets/twitter.svg';
...
const icons = [
<Github />,
<Facebook />,
<Twitter />,
...
];
我想为每个图标应用相同的样式而不需要重复代码并使用CSS-in-JS
。
目前我的解决方案存在一些问题:
// Works but,
// I want to use CSS-in-JS like styled-components
// for easier maintenance
const iconStyle = {
width: 50,
height: 50
};
const SocialBar = () => (
<IconBar as={FlexBox}>
{icons.map((icon, key) => (
<div key={key}>{React.cloneElement(icon, iconStyle)}</div>
))}
</IconBar>
);
// Works but,
// there are too many icons
const SocialBar = () => (
<IconBar as={FlexBox}>
<Github style={iconStyle} />
<Facebook style={iconStyle} />
...
</IconBar>
);
这样的 svg
组件样式将不起作用:
// Won't override the width="24" height="24" properties
const StyledIcon = styled(Github)`
width: 50;
height: 50;
`;
这是一种方法。
//Github.js
import React from "react";
export default function Github({height, width}) {
return (
<svg width={width} height={height} viewBox="0 0 24 24"> ... </svg>
);
}
然后你想在哪里使用它。
<Github height={24} width={24} />
相对于您已有的代码示例,我不完全确定您的要求是什么。您是否试图避免使用 React.cloneElement
?将图标数组作为函数,而不是 jsx 元素。 map
将其应用于 jsx 版本并将样式应用于每个
const icons = [
Github,
Facebook,
Twitter,
]
buildIcons() {
const style = {
//..
}
return icons.map((icon, idx) => (
<icon style={style} key={idx}/>
))
}
使用索引作为键是可行的,但如果你能找到每个图标唯一的不同属性,那就更好了。
您可以用一个元素(如 i
)包裹 SVG,并使用 styled-component 中定义的一些 CSS 为其中的任何 svg
子元素设置样式(您也可以定位 g
和 path
)。不幸的是,SVG 使用起来非常棘手,因此您 可能 需要手动 copy/paste 将 SVG xml 放入 JS 文件中(如果您使用 CRA, you can import a ReactComponent from an SVG).
工作示例(copy/pasted SVG 到 JS 文件——第一个示例是默认的,第二个示例传入 props,第三个示例传入多个 props):
Icon/Icon.js(此组件接受样式化组件生成的 className
和任何放置在其中的 children
)
import React from "react";
import PropTypes from "prop-types";
const Icon = ({ className, children }) => (
<i className={className}>{children}</i>
);
Icon.propTypes = {
className: PropTypes.string.isRequired,
children: PropTypes.node.isRequired
};
export default Icon;
Icon/index.js(这将为上面的 Icon
组件设置样式;随后它将设置 children
的样式)
import styled from "styled-components";
import Icon from "./Icon";
const StyledIcon = styled(Icon)`
margin: 0 20px;
svg {
fill: ${({ fill }) => fill || "#03a9f3"};
height: ${({ dimension }) => dimension || "50px"};
width: ${({ dimension }) => dimension || "50px"};
}
`;
export default StyledIcon;