【问题标题】:How do I use an SVG as an IconComponent in a Material UI Select?如何在 Material UI Select 中使用 SVG 作为 IconComponent?
【发布时间】:2021-10-25 16:09:09
【问题描述】:

我有

import CaretDownIcon from 'src/../public/images/svg/caret-down.svg';


      <Select
        className={selectClassName}
        data-testid={testId}
        // IconComponent={<SvgIcon>{CaretDownIcon}</SvgIcon>}
        // IconComponent={CaretDownIcon}
        inputProps={{
          name,
          id: labelId,
        }}
        {...rest}
      >

我尝试了这两条评论线,但没有骰子。正确的方法是什么?

【问题讨论】:

    标签: reactjs svg material-ui


    【解决方案1】:

    您需要为您的自定义 svg 图标创建一个组件。从 svg 文件中复制路径,制作如下图所示的组件:

    function CustomSvgIcon(props) {
      return (
        <SvgIcon {...props}>
          <path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z" />
        </SvgIcon>
      );
    }
    

    然后您可以将其与IconComponent={CustomSvgIcon} 一起使用。

    这是一个完整的工作示例:

    import React from "react";
    import PropTypes from "prop-types";
    import { withStyles } from "@material-ui/core/styles";
    import InputLabel from "@material-ui/core/InputLabel";
    import MenuItem from "@material-ui/core/MenuItem";
    import FormControl from "@material-ui/core/FormControl";
    import Select from "@material-ui/core/Select";
    import SvgIcon from "@material-ui/core/SvgIcon";
    
    const styles = (theme) => ({
      root: {
        display: "flex",
        flexWrap: "wrap"
      },
      formControl: {
        margin: theme.spacing.unit,
        minWidth: 120
      },
      selectEmpty: {
        marginTop: theme.spacing.unit * 2
      }
    });
    function CustomSvgIcon(props) {
      return (
        <SvgIcon {...props}>
          <path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z" />
        </SvgIcon>
      );
    }
    
    class SimpleSelect extends React.Component {
      state = {
        age: "",
        name: "hai"
      };
    
      handleChange = (event) => {
        this.setState({ [event.target.name]: event.target.value });
      };
    
      render() {
        const { classes } = this.props;
    
        return (
          <form className={classes.root} autoComplete="off">
            <FormControl className={classes.formControl}>
              <InputLabel htmlFor="age-simple">Age</InputLabel>
              <Select
                value={this.state.age}
                onChange={this.handleChange}
                inputProps={{
                  name: "age",
                  id: "age-simple"
                }}
                IconComponent={CustomSvgIcon}
              >
                <MenuItem value="">
                  <em>None</em>
                </MenuItem>
                <MenuItem value={10}>Ten</MenuItem>
                <MenuItem value={20}>Twenty</MenuItem>
                <MenuItem value={30}>Thirty</MenuItem>
              </Select>
            </FormControl>
          </form>
        );
      }
    }
    
    SimpleSelect.propTypes = {
      classes: PropTypes.object.isRequired
    };
    
    export default withStyles(styles)(SimpleSelect);
    

    也可以从导入的 SVG 文件创建 React 组件,但这取决于您的构建配置。如果您使用的是create-react-app,那么这将起作用(有关详细信息,请参阅this article)。

    以下是使用导入方法的示例。这使用 import { ReactComponent as TestSvgAsComponent } from "./test.svg"; 从 SVG 文件中获取 React 组件。另一个必要的步骤是添加将由 SvgIcon 应用的样式(在示例中,classes.icon 来自 useIconStyles)。

    import React from "react";
    import PropTypes from "prop-types";
    import { withStyles, makeStyles } from "@material-ui/core/styles";
    import InputLabel from "@material-ui/core/InputLabel";
    import MenuItem from "@material-ui/core/MenuItem";
    import FormControl from "@material-ui/core/FormControl";
    import Select from "@material-ui/core/Select";
    import { ReactComponent as TestSvgAsComponent } from "./test.svg";
    import clsx from "clsx";
    const styles = (theme) => ({
      root: {
        display: "flex",
        flexWrap: "wrap"
      },
      formControl: {
        margin: theme.spacing.unit,
        minWidth: 120
      },
      selectEmpty: {
        marginTop: theme.spacing.unit * 2
      }
    });
    const useIconStyles = makeStyles({
      // This is a copy of the styles from https://github.com/mui-org/material-ui/blob/v4.12.3/packages/material-ui/src/SvgIcon/SvgIcon.js#L10
      icon: {
        fill: "currentColor",
        width: "1em",
        height: "1em",
        display: "inline-block",
        fontSize: "1.5rem",
        transition: "fill 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms",
        flexShrink: 0,
        userSelect: "none"
      }
    });
    
    function CustomSvgIcon({ className, ...other }) {
      const classes = useIconStyles();
      return (
        <TestSvgAsComponent className={clsx(classes.icon, className)} {...other} />
      );
    }
    class SimpleSelect extends React.Component {
      state = {
        age: "",
        name: "hai"
      };
    
      handleChange = (event) => {
        this.setState({ [event.target.name]: event.target.value });
      };
    
      render() {
        const { classes } = this.props;
    
        return (
          <form className={classes.root} autoComplete="off">
            <FormControl className={classes.formControl}>
              <InputLabel htmlFor="age-simple">Age</InputLabel>
              <Select
                value={this.state.age}
                onChange={this.handleChange}
                inputProps={{
                  name: "age",
                  id: "age-simple"
                }}
                IconComponent={CustomSvgIcon}
              >
                <MenuItem value="">
                  <em>None</em>
                </MenuItem>
                <MenuItem value={10}>Ten</MenuItem>
                <MenuItem value={20}>Twenty</MenuItem>
                <MenuItem value={30}>Thirty</MenuItem>
              </Select>
            </FormControl>
          </form>
        );
      }
    }
    
    SimpleSelect.propTypes = {
      classes: PropTypes.object.isRequired
    };
    
    export default withStyles(styles)(SimpleSelect);
    

    相关文档:

    相关答案:

    【讨论】:

    • 但是我没有&lt;path&gt;等。我只有SVG文件,那我怎么用呢?
    • &lt;path&gt; 元素将位于 SVG 文件中。在文本编辑器中打开文件并复制该部分。
    • 有什么方法可以导入吗?
    • 查看我的答案的补充(第二个例子)。
    猜你喜欢
    • 1970-01-01
    • 2016-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-29
    • 1970-01-01
    • 2018-09-25
    • 2020-11-08
    相关资源
    最近更新 更多