You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用vite-plugin-svgr为SVG添加<title>子元素(无需使用ref)?

解决vite-plugin-svgr添加SVG 子元素的问题 <a class="header-anchor" href="#解决vite-plugin-svgr添加svg-子元素的问题" aria-hidden="true">#</a></h1> <p>你需要给SVG添加<code><title></code>子元素而非SVG标签的<code>title</code>属性,以下是两种无需使用ref的可行方案:</p> <h2 id="方案一:修改vite-plugin-svgr配置,全局支持title-prop">方案一:修改vite-plugin-svgr配置,全局支持title prop <a class="header-anchor" href="#方案一:修改vite-plugin-svgr配置,全局支持title-prop" aria-hidden="true">#</a></h2> <p>通过自定义svgr的组件模板,让所有导入的SVG组件自动支持<code>title</code>参数,并将其渲染为第一个子元素:</p> <p>在<code>vite.config.js</code>中配置:</p> <pre class="hljs"><code class="language-javascript volc-pre-code">import { defineConfig } from 'vite'; import svgr from 'vite-plugin-svgr'; export default defineConfig({ plugins: [ svgr({ svgrOptions: { template: (variables, { tpl }) => { return tpl` ${variables.imports}; ${variables.interfaces}; const ${variables.componentName} = (${variables.props}) => { const { title, ...restProps } = ${variables.props}; return ( <svg {...restProps}> {title && <title>{title}</title>} ${variables.children} </svg> ); }; export default ${variables.componentName}; `; }, }, }), ], }); </code></pre> <p>配置完成后,直接给SVG组件传<code>title</code>即可:</p> <pre class="hljs"><code class="language-jsx volc-pre-code">import { ReactComponent as Circle } from "./assets/circle.svg"; const Icon = () => { return ( <div> <Circle title="icon title" /> </div> ); }; </code></pre> <p>最终生成的DOM结构:</p> <pre class="hljs"><code class="language-html volc-pre-code"><svg height="100" width="100" xmlns="http://www.w3.org/2000/svg"> <title>icon title</title> <circle r="45" cx="50" cy="50" fill="red"></circle> </svg> </code></pre> <h2 id="方案二:封装高阶组件(hoc),单个组件处理">方案二:封装高阶组件(HOC),单个组件处理 <a class="header-anchor" href="#方案二:封装高阶组件(hoc),单个组件处理" aria-hidden="true">#</a></h2> <p>如果不想修改全局配置,可以封装一个高阶组件,给目标SVG组件插入<code><title></code>元素:</p> <pre class="hljs"><code class="language-jsx volc-pre-code">import React from 'react'; const withSvgTitle = (SvgComponent) => { return ({ title, ...props }) => { const svgElement = <SvgComponent {...props} />; // 保留原SVG的子元素,同时插入title作为第一个子元素 return React.cloneElement(svgElement, {}, [ title && <title key="svg-title">{title}</title>, ...React.Children.toArray(svgElement.props.children) ]); }; }; </code></pre> <p>使用方式:</p> <pre class="hljs"><code class="language-jsx volc-pre-code">import { ReactComponent as Circle } from "./assets/circle.svg"; // 包装目标SVG组件 const CircleWithTitle = withSvgTitle(Circle); const Icon = () => { return ( <div> <CircleWithTitle title="icon title" /> </div> ); }; </code></pre> <h3 id="为什么你之前的方法无效?">为什么你之前的方法无效? <a class="header-anchor" href="#为什么你之前的方法无效?" aria-hidden="true">#</a></h3> <ul> <li>直接传<code>title="icon title"</code>:vite-plugin-svgr会将其作为SVG标签的属性,而非生成<code><title></code>子元素;</li> <li>你的<code>cloneElement</code>写法:直接替换了原SVG组件的所有子元素,导致原有的<code><circle></code>丢失,正确做法是保留原组件的子元素并插入title。</li> </ul> <p>内容的提问来源于stack exchange,提问作者netanel</p>
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 00:53:16