JSX中的SVG-如何转换defs标签

fey*_*chu 4 css svg jsx reactjs

我有一些SVG,它们的defs属性带有style标签。像这样:

<svg ...>
  <defs>
    <style>.cls-1,.cls-7{fill:#b2488d;}.cls-1,.cls-2,.cls-3,.cls-4,.cls-5,.cls-6{stroke:#671f4d;}</style>
  </defs>
  ...
</svg>
Run Code Online (Sandbox Code Playgroud)

我想在React中使用这些SVG,所以我想将它们转换为有效的JSX。我已经使用过svg2jsx之类的工具,但是它们将defs标签剥离了,所以样式属性不再存在。有没有一种方法可以通过在JSX中转换SVG 来保留defs带有style标签的?还是在这种情况下无法使用CSS类?

Nip*_*pun 7

您可以保留样式而无需任何转换。为此,使用 {` 和 `} 将所有 CSS 类包装在 style 标签中。现在你的 SVG 变成了这样

<svg ...>
  <defs>
    <style>{`.cls-1,.cls-7{fill:#b2488d;}.cls-1,.cls-2,.cls-3,.cls-4,.cls-5,.cls-6{stroke:#671f4d;}`}</style>
  </defs>
  ...
</svg>
Run Code Online (Sandbox Code Playgroud)

这将毫无问题地呈现。


lum*_*mio 5

如果您在Illustrater中创建了SVG,请在CSS属性设置为的情况下进行保存Presentation Attributes。这样,您将不会以CSS类结尾,并且可以直接更改所有属性。

我导出了一个看起来像这样的SVG:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve">
<g>
    <rect x="15.5" y="15.5" fill="#FFFFFF" width="44" height="44"/>
    <path d="M59,16v43H16V16H59 M60,15H15v45h45V15L60,15z"/>
</g>
<g>
    <path fill="#FFFFFF" d="M60.5,81.5c-12.1,0-22-9.9-22-22s9.9-22,22-22s22,9.9,22,22S72.6,81.5,60.5,81.5z"/>
    <path d="M60.5,38C72.4,38,82,47.6,82,59.5S72.4,81,60.5,81S39,71.4,39,59.5S48.6,38,60.5,38 M60.5,37C48.1,37,38,47.1,38,59.5
        S48.1,82,60.5,82S83,71.9,83,59.5S72.9,37,60.5,37L60.5,37z"/>
</g>
</svg>
Run Code Online (Sandbox Code Playgroud)

然后,我摆脱了所有不必要的标记,只在组件内部使用了它:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve">
<g>
    <rect x="15.5" y="15.5" fill="#FFFFFF" width="44" height="44"/>
    <path d="M59,16v43H16V16H59 M60,15H15v45h45V15L60,15z"/>
</g>
<g>
    <path fill="#FFFFFF" d="M60.5,81.5c-12.1,0-22-9.9-22-22s9.9-22,22-22s22,9.9,22,22S72.6,81.5,60.5,81.5z"/>
    <path d="M60.5,38C72.4,38,82,47.6,82,59.5S72.4,81,60.5,81S39,71.4,39,59.5S48.6,38,60.5,38 M60.5,37C48.1,37,38,47.1,38,59.5
        S48.1,82,60.5,82S83,71.9,83,59.5S72.9,37,60.5,37L60.5,37z"/>
</g>
</svg>
Run Code Online (Sandbox Code Playgroud)
const Image = ( props ) => {
  const {
    hideSquare,
    hideCircle,
  } = props;
  
  const colorSquare = props.colorSquare || '#fff';
  const colorCircle = props.colorCircle || '#fff';
  
  return (
    <svg x="0px" y="0px" viewBox="0 0 100 100">
      { hideSquare ? null : (
        <g>
          <rect x="15.5" y="15.5" fill={ colorSquare } width="44" height="44"/>
          <path d="M59,16v43H16V16H59 M60,15H15v45h45V15L60,15z"/>
        </g>
      ) }
      { hideCircle ? null : (
        <g>
          <path fill={ colorCircle } d="M60.5,81.5c-12.1,0-22-9.9-22-22s9.9-22,22-22s22,9.9,22,22S72.6,81.5,60.5,81.5z"/>
          <path d="M60.5,38C72.4,38,82,47.6,82,59.5S72.4,81,60.5,81S39,71.4,39,59.5S48.6,38,60.5,38 M60.5,37C48.1,37,38,47.1,38,59.5
            S48.1,82,60.5,82S83,71.9,83,59.5S72.9,37,60.5,37L60.5,37z"/>
        </g>
      ) }
    </svg>
  );
};

class Wrapper extends React.Component {
  constructor( props ) {
    super( props );
    
    // Set default state
    this.state = {
      selectedColor: 'lightgreen',
      hideSquare: false,
      hideCircle: false,
    };
  }
  
  // onInput callback
  changeColor = ( e ) => {
    this.setState( { selectedColor: e.target.value } );
  }
  
  changeVisibility = ( e ) => {
    const { name, checked } = e.target;
    this.setState( { [ name ]: checked } );
  }
  
  render() {
    return (
      <div>
        <select onInput={ this.changeColor }>
          <option>lightgreen</option>
          <option>pink</option>
          <option>red</option>
        </select><br />
        <label><input type="checkbox" name="hideSquare" onChange={ this.changeVisibility } /> hideSquare</label>
        <label><input type="checkbox" name="hideCircle" onChange={ this.changeVisibility } /> hideCircle</label><br />
        <Image
          hideSquare={ this.state.hideSquare }
          hideCircle={ this.state.hideCircle }
          colorSquare={ this.state.selectedColor }
          colorCircle={ this.state.selectedColor }
        />
      </div>
    );
  }
}

ReactDOM.render( <Wrapper />, document.getElementById( 'app' ) );
Run Code Online (Sandbox Code Playgroud)
svg {
  width: 200px;
  height: 200px;
}
Run Code Online (Sandbox Code Playgroud)