【问题标题】:Inline SVG in react 16React 16 中的内联 SVG
【发布时间】:2018-05-21 20:04:06
【问题描述】:

我有一个 SVG 文件,我想在我的 react 组件中用作图标。

<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 409.6 405.76"><defs><style>.cls-1{fill:none;}.cls-2{clip-path:url(#clip-path);}</style><clipPath id="clip-path" transform="translate(-478 -181.08)"><rect class="cls-1" x="478" y="181" width="409.92" height="406.8"/></clipPath></defs><title>test</title><g class="cls-2"><path class="ofj" d="M682.8,396.06c50.72,0,91.84-48.13,91.84-107.49,0-82.33-41.12-107.49-91.84-107.49S591,206.24,591,288.57c0,59.36,41.12,107.49,91.84,107.49Zm0,0" transform="translate(-478 -181.08)"/><path d="M885.6,554.28,839.27,449.9a23.3,23.3,0,0,0-10.48-11.15l-71.91-37.43a4.66,4.66,0,0,0-4.93.41,113.41,113.41,0,0,1-138.3,0,4.67,4.67,0,0,0-4.94-.41l-71.9,37.43a23.24,23.24,0,0,0-10.47,11.15L480,554.28a23.16,23.16,0,0,0,21.18,32.56H864.42a23.17,23.17,0,0,0,21.18-32.56Zm0,0" transform="translate(-478 -181.08)"/></g></svg>

我希望能够动态更改填充颜色。我读过最好使用 SVG 'inline',我尝试用 &lt;use&gt; 引用它,但它不起作用(它没有显示......)

<svg className="icon-avator">
  <use xlinkHref="./assets/avatar.svg" />
</svg>

我怎样才能做到这一点?

【问题讨论】:

  • 指向一个片段而不是整个文件。 用于完整文件。

标签: css reactjs svg


【解决方案1】:

React JSX 可以生成 SVG,就像它使用 HTML 一样。把SVG写成组件的“标记”,用props控制fill属性(也可以改变样式):

const Icon = ({ fill }) => (
  <svg viewBox="0 0 409.6 405.76" fill={ fill }>
      <path d="M682.8,396.06c50.72,0,91.84-48.13,91.84-107.49,0-82.33-41.12-107.49-91.84-107.49S591,206.24,591,288.57c0,59.36,41.12,107.49,91.84,107.49Zm0,0" transform="translate(-478 -181.08)"/>
      <path d="M885.6,554.28,839.27,449.9a23.3,23.3,0,0,0-10.48-11.15l-71.91-37.43a4.66,4.66,0,0,0-4.93.41,113.41,113.41,0,0,1-138.3,0,4.67,4.67,0,0,0-4.94-.41l-71.9,37.43a23.24,23.24,0,0,0-10.47,11.15L480,554.28a23.16,23.16,0,0,0,21.18,32.56H864.42a23.17,23.17,0,0,0,21.18-32.56Zm0,0" transform="translate(-478 -181.08)"/>
  </svg>
);

ReactDOM.render(
  <Icon fill="red" />,
  demo
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="demo"></div>

【讨论】:

  • 很酷,谢谢 :) 那么您知道使 Icon 组件动态以能够显示不同 SVG 标记的最佳方法是什么吗?也许是一个微不足道的问题,但我的大脑现在已经死了!
  • 每个符号都可以是一个组件,你可以有 SymbolA、SymbolB 等。现在你可以用一个通用的 Icon 组件来包装它们,根据一个属性选择符号。
  • 为了让它更干净,你可以删除&lt;title&gt;标签,从&lt;g&gt;中取出&lt;path&gt;s并删除它,从&lt;path&gt;s中删除fill并将其设置在@内987654330@ :)
  • 是否可以从 svg 文件中导入或以其他方式加载标记,而不是对 svg 标记进行硬编码?
  • @olefrank - 您始终可以将 svg 作为图像加载。另一种选择是使用react-svg-loader - 一个用于将 svg 作为 React 组件加载的 webpack、rollup、babel 的加载器。
【解决方案2】:

对于登陆此页面的人,还有一个 webpack 加载器,它可以从 SVG 文件生成 React 组件。 react-svg-loader

如果您正在使用 create-react-app,您可能想暂时退出。但要知道这一点;有关于在 CRA 和it's on the 2.0.0 roadmap apparently 中集成这样的加载程序的讨论@

【讨论】:

    【解决方案3】:

    另一种选择是不使用外部资源,所以不要这样做

    <use href="/path/to/icon.svg" />
    

    用这样的符号(例如https://www.npmjs.com/package/svg-sprite)创建一个精灵:

    <svg ...>
      // icon contents here, except `svg` tag became `symbol` tag
      <symbol id="icon-id-inside-the-sprite" ...>
        // ...
      </symbol>
      // may be add more icons
    </svg>
    

    将它内嵌到你的 HTML 中并用 display: none 样式隐藏,然后像这样使用它

    <use href="#icon-id-inside-the-sprite" />
    

    现在您应该能够从外部 CSS 定位其内部类。

    【讨论】:

      【解决方案4】:

      还有一个 npm 包可以将所有 svg 元素转换为正确的 JSX,以防其他人来到这里并遇到类似问题。

      https://www.npmjs.com/package/convert-svg-react

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-20
        • 1970-01-01
        • 2017-11-01
        • 2021-08-23
        • 2020-09-08
        • 2012-02-19
        • 2018-11-22
        • 1970-01-01
        相关资源
        最近更新 更多