我有一个组件,它接收 :itemName 并输出包含图像的 html 包。每个捆绑包的图像都不同。
这是我所拥有的:
import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
import SVGInline from "react-svg-inline";
export default (props) => (
<NavLink className="hex" activeClassName="active" to={'/hex/' + props.itemName}> {React.createElement(SVGInline, {svg: props.itemName})} </NavLink>
)
我怎样才能让这个组件工作?
我知道,如果我只是显式导入所有图像,我可以像这样调用我的图像......
import SVGInline from "react-svg-inline";
import SASSSVG from "./images/sass.svg";
<NavLink className="hex" activeClassName="active" to="/hex/sass"><SVGInline svg={ SASSSVG } /></NavLink>
这可行,但由于我需要包含 ~60 个 svgs,所以它添加了很多多余的代码。
另外,我发现在这个问题中这段代码......
import * as IconID from './icons';
但这似乎不起作用(这是问题的一部分,而不是答案),而且答案有点太不具体,无法回答我要问的问题。
我还发现了这个问题,但同样有一个答案(尽管未经批准)所包含的问题多于它的答案。所以,在安装了react-svg之后,我设置了一个测试来看看答案是否像这样工作......
import React, { Component } from 'react';
import ReactDOM from 'react-dom'
import { NavLink } from 'react-router-dom';
import ReactSVG from 'react-svg'
export default (props) => (
<NavLink className="hex" activeClassName="active" to={'/hex/' + props.itemName}>
<ReactSVG
path={"images/" + props.itemName + ".svg"}
callback={svg => console.log(svg)}
className="example"
/>
</NavLink>
)
但是,正如该问题的OP所问的那样,即使将整个图像文件夹复制到构建文件夹中,页面也找不到我的svg。我也尝试过“./images/”
我觉得我只是错过了最后一条关键信息,在搜索了过去的一天之后,我希望有人能够识别我所缺少的信息。
如果使用 React,我强烈怀疑你也在使用 Webpack。您可以使用
require.context
代替 es6 import
,Webpack 将在构建时为您解决。
require.context ( folder, recurse, pattern )
- folder - 字符串 - 开始扫描文件的文件夹路径。
- recurse - 布尔值 - 是否递归扫描文件夹。
- pattern - RegExp - 描述要包含哪些文件的匹配模式。
每个示例的第一行...
const reqSvgs = require.context ( './images', true, /\.svg$/ )
... 创建一个 Require Context,将
*.svg
文件夹中的所有 images
文件路径映射到导入。这为我们提供了一个名为 reqSvgs
的专门 Require 函数,并带有一些附加属性。
reqSvgs
的属性之一是keys
方法,它返回所有有效文件路径的列表。
const allSvgFilepaths = reqSvgs.keys ()
我们可以将这些文件路径之一传递到
reqSvgs
来获取导入的图像。
const imagePath = allSvgFilePaths[0]
const image = reqSvgs ( imagePath )
此 api 对于此用例来说是有限制且不直观的,因此我建议将集合转换为更常见的 JavaScript 数据结构,以使其更易于使用。
转换过程中将导入每个图像。小心,因为这可能是一把步枪。但它提供了一种相当简单的机制,用于将多个文件复制到构建文件夹,而其他源代码可能永远不会显式引用该文件夹。
这里有 3 个可能有用的转换示例。
创建导入文件的数组。
const reqSvgs = require.context ( './images', true, /\.svg$/ )
const paths = reqSvgs.keys ()
const svgs = paths.map( path => reqSvgs ( path ) )
创建一个对象数组,每个对象对于一张图像来说都是
{ path, file }
。
const reqSvgs = require.context ( './images', true, /\.svg$/ )
const svgs = reqSvgs
.keys ()
.map ( path => ({ path, file: reqSvgs ( path ) }) )
创建一个对象,其中每个路径都是其匹配文件的密钥。
const reqSvgs = require.context ('./images', true, /\.svg$/ )
const svgs = reqSvgs
.keys ()
.reduce ( ( images, path ) => {
images[path] = reqSvgs ( path )
return images
}, {} )
SurviveJS 在这里
SurviveJS Webpack 动态加载给出了更通用的示例
require.context
。
偶然发现这个问题 - 我最初有“已接受的答案”,但我对每个 svg 发出了 http 请求,这触发了速率限制。所以我最终得到了接受的答案和 @karthik 提议的组合 - 在 request.context 中使用加载器
从 CRA 2.0 开始,包含 @svgr 以将 svg 作为 React 组件导入。
const reqSvgs = require.context('!@svgr/webpack!flag-icon-css/flags/4x3', true, /\.svg$/)
所以这里我们结合了 svg 加载器和 require.context
const flagMap = reqSvgs.keys().reduce((images, path) => {
const key = path.substring(path.lastIndexOf('/') + 1, path.lastIndexOf('.'))
images[key] = reqSvgs(path).default
return images
}, {})
然后我们将所有这些映射到一个 json 对象中,以便我们可以使用键查找
在 jsx 中渲染 svg:
const Flag = flagMap['dk']
return (
<Flag />
)
快乐的日子,svgs 包含在捆绑中,并且没有单独的 http 请求🎊🎉
您可以使用单个 SVG 精灵,而不是多个 SVG 文件。
SVG sprite 可以使用 svg-sprite-generator:
从 SVG 文件目录生成svg-sprite-generate -d images -o images/sprite.svg
然后像这样使用它:
import React from 'react';
import { NavLink } from 'react-router-dom';
import sprite from './images/sprite.svg';
export default (props) => (
<NavLink className="hex" activeClassName="active" to={'/hex/' + props.itemName}>
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="30">
<use xlinkHref={`${sprite}#${props.itemName}`} />
</svg>
</NavLink>
)
最好的方法是使用节点模块,例如 [SVG to React Loader] (https://github.com/jhamlet/svg-react-loader)
对于 Vite(Vue,但应该适用于其他库)只需使用
const iconsModule = import.meta.glob('@/path/*.svg');
然后您可以迭代路径并获取带或不带格式名称的文件名
for (const path in iconsModule) {
const icon = path.split('/').slice(-1)[0];
this.icons.push(icon);
}
您可以简单地创建一个函数,该函数接受参数“名称”(您的 svg 图标名称)并返回您的 svg 代码。
import React from 'react'
export function getIcon(name){
switch(name) {
case 'back':
return (
// your svg code here
<svg></svg>
)
}
}
然后您可以将其导入到任何地方,只需用您想要的图标名称来调用它即可。
import { getIcon } from './utils'
render() {
return (
<div>
<span>{ getIcon('back') }</span>
</div>
)
}