如何使用 React Component 在 UI 中显示 svg 图标(. svg 文件) ?

我已经看到了许多用于 svg on response 的库,但是没有一个告诉我如何在 response 组件中导入 svg 文件。我曾经看到过一些代码,它们讨论如何使 svg 代码作出反应,而不是使用。Svg 图标作为图像,并在用户界面中显示它。

请让我知道是否有方法嵌入图标。

355890 次浏览

如果映像是远程托管的,则可以直接使用带有 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 的简单导入。

import MyImageSvg from '../../path/to.svg';

只要记住使用一个加载程序,例如 Webpack:

 {
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;
}

你也可以导入 .svg.jpg.png.ttf等文件,比如:

  ReactDOM.render(
<img src={require("./svg/kiwi.svg")}/>,
document.getElementById('root')
);

如果你使用 Create-response-app 2.0,你现在可以这样做:

import { ReactComponent as YourSvg } from './your-svg.svg';

然后使用它,就像你通常使用一个组件:

const App = () => (
<div>
<YourSvg />
</div>
);

注意,新名称必须大写,否则 React 不会将其识别为组件。

如果您的 SVG 包含 sprites,那么您可以使用下面这个组件。我们有三组或四组精灵... 显然,如果你只有一个精灵文件,你可以把那个部分拉出来。

雪碧组件:

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>
)
}
}

在《反应》的其他地方,你会:

import Sprite from './Sprite';


render()
{
...
<Sprite label="No Current Value" group='base' sprite='clock' />
}

示例来自我们的‘ base’sprite 文件,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>

只需在图像的 src 中写入带路径的请求即可。 例如:

<img alt="Clock" src={require('../assets/images/search_icon.svg')}/>

如果你有的话。局部的 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"));


快乐编码:”)

资源从反应网站和工作后,我多次搜索: Https://create-react-app.dev/docs/adding-images-fonts-and-files/

如果希望使用 SVG 文件作为 React 组件执行定制和 不要使用 create-response-app,请执行以下操作:

  1. 安装名为 Svgr的 Webpack 加载程序
yarn add --dev @svgr/webpack
  1. 更新你的 webpack.config.js
  ...
module: {
rules: [
...
// SVG loader
{
test: /\.svg$/,
use: ['@svgr/webpack'],
}
],
},
...
  1. 导入 SVG 文件作为 React 组件
import SomeImage from 'path/to/image.svg'


...


<SomeImage width={100} height={50} fill="pink" stroke="#0066ff" />

由于上面提到的一些原因,在我按照建议像这样添加 .default之前,这些方法对我不起作用:

<div>
<img src={require('../../mySvgImage.svg').default} alt='mySvgImage' />
</div>

很难相信添加一个自定义图标是如此复杂。我发现了一个与上面提到的类似的解决方案,但是对我来说,直到添加了 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 才能正常工作

在这里,我找到了一个简单的解决方案,没有弹出,我们不需要安装其他依赖,如 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 配置。

  1. 转到 node_modules/react-scripts/config/webpack.config.js
  2. 转到 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. 在上面的 文件加载程序中添加 以下行。
         // #1 Custom loader for handling svg images
{
test: /\.svg$/,
use: ['@svgr/webpack']
},

就是这样

如何在反应元件内部使用 SVG?

import ChevronRight from '../../../assets/icons/feather/chevron-right.svg';


const Links = () => {
return (
<ChevronRight height={25} width={25} />
);
};


export default Links;

您可以通过此 工地将 SVG 转换为可行的 React 组件

我很想知道如何从远程主机(例如 CDN)添加 SVG 作为 ReactComponent。我会把它当做

Http://url/file.svg 但这并不适用于我的用例。

我想看看我能不能把它用作

从“ http://url/file.svg"”导入{ ReactComponent as svgIcon } ;

如果您的 React 项目中有“材料用户界面”库,您可以执行以下操作:

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>
);
}

文件: https://mui.com/components/icons/#svgicon

作为附加信息,如果您正在使用 NextJs,显示 SVG 的最简单方法是导入您的 SVG,然后使用 <Image /> NextJs 组件:

import Image from 'next/image';
import SVGIcon from 'your/svg/path/icon.svg';


<Image
src={SVGIcon}
alt="Logo - SVG"
width="40"
height="40"
/>