如何在 Material-UI 中的 SvgIcon 中使用 SVG 文件

How to use an SVG file in a SvgIcon in Material-UI

我有一个 SVG 文件,我想用它制作一个 SvgIcon 组件,我应该怎么做?

documentation 中,所有示例都使用预定义的 Material 图标或奇怪的符号 <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" />,我不知道它是什么!

<path />是一个SVG路径,即SVG的内部位。 SvgIcon 组件确实应该能够采用路径,但它没有:(

您可以创建一个类似 https://github.com/callemall/material-ui/blob/56c113217d7d05d8bb0712771b727df81984d04b/src/svg-icons/action/home.js

的组件

用你的 svg 源代替 path。 (我建议使用 https://jakearchibald.github.io/svgomg/ 将其缩小一点)

如果制作多个图标,您可能不想重复接受的答案中引用的示例中的所有样板。您可以使用包装器组件生成器,例如:

const wrapSvgPath = (path, viewBox='0 0 24 24') => (props) => (
    <SvgIcon {...props} viewBox={viewBox}>{path}</SvgIcon>
)

像这样使用:

const facebookPath = (<path
        d="M17,2V2H17V6H15C14.31,6 14,6.81 14,7.5V10H14L17,10V14H14V22H10V14H7V10H10V6A4,4 0 0,1 14,2H17Z" />
)
export const FacebookIcon = wrapSvgPath(facebookPath)

要获取SvgIcon的路径,用文本编辑器打开svg文件,复制相应的路径表达式。

1。使用 <Icon/> 组件和 <img/> 元素

为了将 SVG 文件用作图标,我使用了 <Icon/> 组件,其中包含一个 <img/> 元素,将 height: 100% 设置为 img 元素和 textAlign: center<Icon/> 组件的 root class 成功了:

JSX:

import Icon from '@material-ui/core/Icon';
import { makeStyles } from '@material-ui/styles';
...

<Icon classes={{root: classes.iconRoot}}>
  <img className={classes.imageIcon} src="/graphics/firebase-logo.svg"/>
</Icon>

样式:

const useStyles = makeStyles({
  imageIcon: {
    height: '100%'
  },
  iconRoot: {
    textAlign: 'center'
  }
});

结果:

更新

正如 Lorenz Haase 在评论中提到的那样,底部的 SVG 有轻微的切割,如果我们使用 flexbox 并继承宽度和高度就可以解决这个问题:

const useStyles = makeStyles({
  imageIcon: {
    display: 'flex',
    height: 'inherit',
    width: 'inherit'
  }
});

2。使用 <SvgIcon/> 组件和 @svgr/webpack webpack 加载器

根据 官方 MUI 文档,我们可以使用 <SvgIcon/> 组件属性并有一个 @svgr/webpack 加载程序来加载 .svg 文件ESM 进口。

Component prop

You can use the SvgIcon wrapper even if your icons are saved in the .svg format. svgr has loaders to import SVG files and use them as React components. For example, with webpack:

// webpack.config.js
{
  test: /\.svg$/,
  use: ['@svgr/webpack'],
}

// ---
import StarIcon from './star.svg';

<SvgIcon component={StarIcon} viewBox="0 0 600 476.6" />

It's also possible to use it with "url-loader" or "file-loader". It's the approach used by Create React App.

// webpack.config.js
{
  test: /\.svg$/,
  use: ['@svgr/webpack', 'url-loader'],
}

// ---
import { ReactComponent as StarIcon } from './star.svg';

<SvgIcon component={StarIcon} viewBox="0 0 600 476.6" />

对我有用的解决方案如下

 import React from 'react';
 import pure from 'recompose/pure';
 import {SvgIcon} from '@material-ui/core';

 let smile = (props) => (
   <SvgIcon {...props} >
<path d="M256,32C132.281,32,32,132.281,32,256s100.281,224,224,224s224-100.281,224-224S379.719,32,256,32z M256,448
c-105.875,0-192-86.125-192-192S150.125,64,256,64s192,86.125,192,192S361.875,448,256,448z M160,192c0-26.5,14.313-48,32-48
s32,21.5,32,48c0,26.531-14.313,48-32,48S160,218.531,160,192z M288,192c0-26.5,14.313-48,32-48s32,21.5,32,48
c0,26.531-14.313,48-32,48S288,218.531,288,192z M384,288c-16.594,56.875-68.75,96-128,96c-59.266,0-111.406-39.125-128-96"/>
   </SvgIcon>
 );

 smile = pure(smile);
 smile.displayName = 'smile';     
 smile.muiName = 'SvgIcon';

 export default smile;

Check this example of material ui icon

您可以将 SVG 直接导入为 React 组件并在 <SvgIcon> 中使用它们:

import React from "react";
import { ReactComponent as Logo } from "./logo.svg";
import SvgIcon from "@material-ui/core/SvgIcon";

const App = () => (
  <SvgIcon>
    <Logo />
  </SvgIcon>
);

export default App;

另请参阅:https://create-react-app.dev/docs/adding-images-fonts-and-files/#adding-svgs

不幸的是,React 似乎还不能渲染所有类型的 SVG(例如用 Inkscape、Illustrator 修改)。但至少 create-react-app 项目中的默认 logo.svg 有效。

在编辑器中打开您的 svg 文件(示例:vscode)。你会看到类似这样的文件结构 ->

<svg width="27" height="28" viewBox="0 0 27 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.91942 27.5138L6.15827 26.984L8.69599 21.1562H8.68852L13.5027 10.3812L18.3542 21.1562H18.3467L21.1083 27.5138H26.2509L15.8687 4.72523L13.5698 0L0.933594 27.5138H5.91942Z" fill="#A7A9AC"/>
</svg>

然后转到您的反应组件,将路径替换为您自己的路径。这应该工作。添加用于自定义设计更改的样式。

SvgIcon 并非用于此目的。更多关于这个@ Github.

您可能正在寻找这个 startIcon={<img src={google}></img>}

import google from "../../Assets/img/google.svg";
import GitHubIcon from "@material-ui/icons/GitHub";
const useStyles = makeStyles((theme) => ({
         root: {
                display: "flex",
                flexDirection: "column",
                margin: theme.spacing(1),
                },
          button: {
               margin: "0.5rem",
                  },
          googleStyle: {
                fillColor: theme.palette.primary.main,
                    },
              }));

export default function ContainedButtons() {
  const classes = useStyles();
   return (
  <div>
  <Button
    variant="contained"
    color="secondary"
    className={classes.button}
    startIcon={<img src={google}></img>}
  >
    Login With Google
  </Button>
  <Button
    variant="contained"
    color="secondary"
    className={classes.button}
    startIcon={<GitHubIcon />}
  >
    Login with GitHub
  </Button>
</div>
);
}
import SvgIcon from '@material-ui/core/SvgIcon'
import Register from "./../../media/register.svg"
import React from 'react';

const getSvgIconMaterial = (Icon: string, props?: any) => {
    return (
        <SvgIcon component="object">
            <embed type="image/svg+xml" src={Icon} style={{ height: "100%" }} />
        </SvgIcon>
    );
};

这样使用

<>{getSvgIconMaterial(Register)}</>

可能不完美,但效果很好。也许添加一个小 padding/margin。

将 svg 文件导入您的 React 应用程序文件夹。 然后在要使用svg图标的文件/组件中使用

import { ReactComponent as MyIcon } from '../svgiconfolder/myicon.svg'

export function MyCompnent(){return <MyIcon />}

如果你想改变颜色使用

import {ReactComponent as MyIcon} from '../svgiconfolder/myicon.svg'

export function MyCompnent(){return <MyIcon fill="#00000"/>}//use the color code in fill or if there is any color attribute in svg file try to use that