【发布时间】:2017-07-06 21:29:13
【问题描述】:
我在 react 上看到了很多 svg 库,但没有一个告诉我如何在 react 组件中导入 svg 文件。我看过一些代码,它谈到将 svg 代码引入反应,而不是使用 .svg 图标作为图像并将其显示在 UI 中。
如果有嵌入图标的方法,请告诉我。
【问题讨论】:
我在 react 上看到了很多 svg 库,但没有一个告诉我如何在 react 组件中导入 svg 文件。我看过一些代码,它谈到将 svg 代码引入反应,而不是使用 .svg 图标作为图像并将其显示在 UI 中。
如果有嵌入图标的方法,请告诉我。
【问题讨论】:
如果您使用create-react-app 2.0,您现在可以这样做:
import { ReactComponent as YourSvg } from './your-svg.svg';
然后像平常使用组件一样使用它:
const App = () => (
<div>
<YourSvg />
</div>
);
【讨论】:
ReactComponent 名称不是可选的。
fill="currentColor",这样你就可以在代码中设置它的样式了。
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
我想向你展示两种方式。
第一个只是所需 SVG 的简单导入。
import MyImageSvg from '../../path/to.svg';
请记住使用加载器,例如网页包:
{
test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/,
include: [Path.join(__dirname, "src/assets")],
loader: "file-loader?name=assets/[name].[ext]"
}
另一种(更优雅的方式)是您可以定义一个 SVG 图标精灵并使用一个组件来获取 SVG 的正确精灵。例如:
import React from "react";
import Icons from "../../assets/icons/icons.svg"; // Path to your icons.svg
import PropTypes from 'prop-types';
const Icon = ({ name, color, size }) => (
<svg className={`icon icon-${name}`} fill={color} width={size} height={size}>
<use xlinkHref={`${Icons}#icon-${name}`} />
</svg>
);
Icon.propTypes = {
name: PropTypes.string.isRequired,
color: PropTypes.string,
size: PropTypes.number
};
export default Icon;
图标精灵(icons.svg)可以定义为:
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="icon-account-group" viewBox="0 0 512 512">
<path d="m256 301l0-41c7-7 19-24 21-60 10-5 16-16 16-30 0-12-4-22-12-28 7-13 18-37 12-60-7-28-48-39-81-39-29 0-65 8-77 30-12-1-20 2-26 9-15 16-8 46-4 62 1 2 2 4 2 5l0 42c0 41 24 63 42 71l0 39c-8 3-17 7-26 10-56 20-104 37-112 64-11 31-11 102-11 105 0 6 5 11 11 11l384 0c6 0 10-5 10-11 0-3 0-74-10-105-11-31-69-48-139-74z m-235 168c1-20 3-66 10-88 5-16 57-35 99-50 12-4 23-8 34-12 4-2 7-6 7-10l0-54c0-4-3-9-8-10-1 0-35-12-35-54l0-42c0-3-1-5-2-11-2-8-9-34-2-41 3-4 11-3 15-2 6 1 11-2 13-8 3-13 29-22 60-22 31 0 57 9 60 22 5 17-6 37-11 48-3 6-5 10-5 14 0 5 5 10 11 10 3 0 5 6 5 11 0 4-2 11-5 11-6 0-11 4-11 10 0 43-16 55-16 55-3 2-5 6-5 9l0 54c0 4 2 8 7 10 51 19 125 41 132 62 8 22 9 68 10 88l-363 0z m480-94c-8-25-49-51-138-84l0-20c7-7 19-25 21-61 4-2 7-5 10-9 4-5 6-13 6-20 0-13-5-23-13-28 7-15 19-41 13-64-4-15-21-31-40-39-19-7-38-6-54 5-5 3-6 10-3 15 3 4 10 6 15 3 12-9 25-6 34-3 15 6 25 18 27 24 4 17-6 40-12 52-3 6-4 10-4 13 0 3 1 6 3 8 2 2 4 3 7 3 4 0 6 6 6 11 0 3-1 6-3 8-1 2-2 2-3 2-6 0-10 5-10 11 0 43-17 55-17 55-3 2-5 5-5 9l0 32c0 4 3 8 7 10 83 31 127 56 133 73 7 22 9 68 10 88l-43 0c-6 0-11 5-11 11 0 6 5 11 11 11l53 0c6 0 11-5 11-11 0-3 0-74-11-105z"/>
</symbol>
<symbol id="icon-arrow-down" viewBox="0 0 512 512">
<path d="m508 109c-4-4-11-3-15 1l-237 269-237-269c-4-4-11-5-15-1-5 4-5 11-1 15l245 278c2 2 5 3 8 3 3 0 6-1 8-3l245-278c4-4 4-11-1-15z"/>
</symbol>
<symbol id="icon-arrow-left" viewBox="0 0 512 512">
<path d="m133 256l269-237c4-4 5-11 1-15-4-5-11-5-15-1l-278 245c-2 2-3 5-3 8 0 3 1 6 3 8l278 245c2 2 4 3 7 3 3 0 6-1 8-4 4-4 3-11-1-15z"/>
</symbol>
<symbol id="icon-arrow-right" viewBox="0 0 512 512">
<path d="m402 248l-278-245c-4-4-11-4-15 1-4 4-3 11 1 15l269 237-269 237c-4 4-5 11-1 15 2 3 5 4 8 4 3 0 5-1 7-3l278-245c2-2 3-5 3-8 0-3-1-6-3-8z"/>
</symbol>
</svg>
您可以在http://fontastic.me/ 上免费定义自己的图标精灵。
以及用法:<Icon name="arrow-down" color="#FFFFFF" size={35} />
并且可能添加一些简单的样式以在任何地方使用图标:
[class^="icon-"], [class*=" icon-"] {
display: inline-block;
vertical-align: middle;
}
【讨论】:
如果图像是远程托管的,您可以直接使用带有img标签的.svg扩展名。
ReactDOM.render(
<img src={"http://s.cdpn.io/3/kiwi.svg"}/>,
document.getElementById('root')
);
这里是小提琴:http://codepen.io/srinivasdamam-1471688843/pen/ZLNYdy?editors=0110
注意:如果您使用任何 Web 应用程序捆绑器(如 Webpack),您需要有相关的文件加载器。
【讨论】:
您还可以导入.svg、.jpg、.png、.ttf等文件,如:
ReactDOM.render(
<img src={require("./svg/kiwi.svg")}/>,
document.getElementById('root')
);
【讨论】:
如果您在本地有 .svg 或图像。首先,您必须安装 svg 所需的加载器和图像的文件加载器。然后你必须先导入你的图标或图像,例如:
import logo from './logos/myLogo.svg' ;
import image from './images/myimage.png';
const temp = (
<div>
<img src={logo} />
<img src={image} />
</div>
);
ReactDOM.render(temp,document.getElementByID("app"));
快乐编码:")
react 网站的资源,经过多次搜索后为我工作: https://create-react-app.dev/docs/adding-images-fonts-and-files/
【讨论】:
由于某些原因,上述方法现在对我有用,在我按照建议添加 .default 之前,如下所示:
<div>
<img src={require('../../mySvgImage.svg').default} alt='mySvgImage' />
</div>
【讨论】:
在这里我找到了一个简单的解决方案,无需弹出,我们不需要安装其他依赖项,如react-app-rewired。因为如果你想使用 SVG 作为组件,我们需要更新 create-react-app 的 webpack 配置。
方法一:
import { ReactComponent as YourSvg } from './your-svg.svg';
const App = () => (
<div>
<YourSvg />
</div>
);
我们可以这样做,但根据上述答案,它仅在create-react-app-2.0 上。
方法二:
我们需要更新create-react-app的webpack配置。
node_modules/react-scripts/config/webpack.config.js。the line number 600。注意:您将在此处看到以下信息
// "file" loader makes sure those assets get served by WebpackDevServer.
// When you `import` an asset, you get its (virtual) filename.
// In production, they would get copied to the `build` folder.
// This loader doesn't use a "test" so it will catch all modules
// that fall through the other loaders.
{
loader: require.resolve('file-loader'),
// Exclude `js` files to keep "css" loader working as it injects
// its runtime that would otherwise be processed through "file" loader.
// Also exclude `html` and `json` extensions so they get processed
// by webpacks internal loaders.
exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
options: {
name: 'static/media/[name].[hash:8].[ext]',
},
},
// ** STOP ** Are you adding a new loader?
// Make sure to add the new loader(s) before the "file" loader.
// #1 Custom loader for handling svg images
{
test: /\.svg$/,
use: ['@svgr/webpack']
},
就是这样??
如何在 react 组件中使用 SVG?
import ChevronRight from '../../../assets/icons/feather/chevron-right.svg';
const Links = () => {
return (
<ChevronRight height={25} width={25} />
);
};
export default Links;
【讨论】:
很难相信添加自定义图标是如此复杂。我找到了与上面发布的解决方案类似的解决方案,但对我来说,在添加 viewBox 信息之前我无法显示图标,这是我直接通过在文本编辑器中打开 SVG 获得的。
//customIcon.js
import React from "react";
import {ReactComponent as ImportedSVG} from "path/to/myIcon.svg";
import { SvgIcon } from '@material-ui/core';
function CustomIcon() {
return(
<SvgIcon component={ImportedSVG} viewBox="0 0 384 512"/>
)
}
export default CustomIcon;
我还遇到了命名空间错误,必须在 SVG 工作之前清理它,遵循 this post 的建议
【讨论】:
只需在图像的 src 中写入带有路径的 require。它会起作用的。 喜欢:
<img alt="Clock" src={require('../assets/images/search_icon.svg')}/>
【讨论】:
如果您想使用 SVG 文件作为 React 组件来执行自定义并且不要使用 create-react-app,请执行以下操作:
yarn add --dev @svgr/webpack
webpack.config.js
...
module: {
rules: [
...
// SVG loader
{
test: /\.svg$/,
use: ['@svgr/webpack'],
}
],
},
...
import SomeImage from 'path/to/image.svg'
...
<SomeImage width={100} height={50} fill="pink" stroke="#0066ff" />
【讨论】:
您可以通过site 将您的 SVG 转换为可行的 React 组件
【讨论】:
我很想知道如何从远程主机(例如 CDN)将 SVG 添加为 ReactComponent。我会用它作为
http://URL/FILE.svg但这不适合我的用例。
我想看看能不能用作
从“http://URL/FILE.svg”导入 { ReactComponent as SvgIcon }
【讨论】:
如果您的 React 项目中有 Material UI 库,您可以执行以下操作:
import React from 'react';
import { SvgIcon } from '@material-ui/core';
export function NewIcon() {
return (
<SvgIcon viewBox="0 0 48 48"> // you may change the viewBox, so the image will fit into it
<path d="M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z" />
</SvgIcon>
)
}
这将在主题更改(浅色/深色)时自动更改 SVG 颜色。另外,您可以根据需要更改其颜色和大小,例如
import React from 'react';
import { styled, SvgIcon } from '@material-ui/core';
const SvgImage = styled(SvgIcon)(() => ({
height: '40px',
width: '40px',
color: 'red',
}));
export function NewIcon() {
return (
<SvgImage viewBox="0 0 48 48">
<path d="M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z" />
</SvgImage>
);
}
【讨论】:
如果您的 SVG 包含精灵,这里有一个您可以使用的组件。我们有三四组精灵……显然,如果你只有一个精灵文件,你就可以把那部分拿出来。
Sprite 组件:
import React from 'react'
import PropTypes from 'prop-types';
export default class Sprite extends React.Component {
static propTypes = {
label: PropTypes.string,
group: PropTypes.string,
sprite: PropTypes.string.isRequired
}
filepath(spriteGroup)
{
if(spriteGroup == undefined) { spriteGroup = 'base' }
return "/asset_path/sprite_" + spriteGroup + ".svg";
}
render()
{
return(
<svg aria-hidden="true" title={this.props.label}>
<use xlinkHref={`${this.filepath(this.props.group)}#${this.props.sprite}`}></use>
</svg>
)
}
}
在 React 的其他地方你会:
import Sprite from './Sprite';
render()
{
...
<Sprite label="No Current Value" group='base' sprite='clock' />
}
来自我们的“基础”精灵文件 sprite_base.svg 的示例:
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<symbol id="clock" viewBox="0 0 512 512">
<path fill="currentColor" d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm216 248c0 118.7-96.1 216-216 216-118.7 0-216-96.1-216-216 0-118.7 96.1-216 216-216 118.7 0 216 96.1 216 216zm-148.9 88.3l-81.2-59c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h14c6.6 0 12 5.4 12 12v146.3l70.5 51.3c5.4 3.9 6.5 11.4 2.6 16.8l-8.2 11.3c-3.9 5.3-11.4 6.5-16.8 2.6z" class="">
</path>
</symbol>
<symbol id="arrow-up" viewBox="0 0 16 16">
<polygon points="1.3,6.7 2.7,8.1 7,3.8 7,16 9,16 9,3.8 13.3,8.1 14.7,6.7 8,0 "> </polygon>
</symbol>
<symbol id="arrow-down" viewBox="0 0 16 16">
<polygon points="14.7,9.3 13.3,7.9 9,12.2 9,0 7,0 7,12.2 2.7,7.9 1.3,9.3 8,16 "> </polygon>
</symbol>
<symbol id="download" viewBox="0 0 48 48">
<line data-cap="butt" fill="none" stroke-width="3" stroke-miterlimit="10" x1="24" y1="3" x2="24" y2="36" stroke-linejoin="miter" stroke-linecap="butt"></line>
<polyline fill="none" stroke-width="3" stroke-linecap="square" stroke-miterlimit="10" points="11,23 24,36 37,23 " stroke-linejoin="miter"></polyline>
<line data-color="color-2" fill="none" stroke-width="3" stroke-linecap="square" stroke-miterlimit="10" x1="2" y1="45" x2="46" y2="45" stroke-linejoin="miter"></line>
</symbol>
</devs>
</svg>
【讨论】: