簡體   English   中英

如何將整個 SVG 圖像文件夾(或如何動態加載它們)導入 React Web App?

[英]How to import an entire folder of SVG images (or how to load them dynamically) into a React Web App?

我有一個組件,它接受一個 :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 - String - 開始掃描文件的文件夾路徑。
  • recurse - Boolean - 是否遞歸掃描文件夾。
  • 模式 - RegExp - 描述要包含哪些文件的匹配模式。

每個示例的第一行...

const reqSvgs = require.context ( './images', true, /\.svg$/ )

... 創建一個 Require Context 將images文件夾中的所有*.svg文件路徑映射到導入。 這為我們提供了一個名為reqSvgs的特殊需求函數, reqSvgs帶有一些附加屬性。

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 Dynamic Loading 中給出了更通用的require.context示例。

偶然發現了這個問題 - 我最初有“接受的答案”,但我對每個 svg 造成了 http 請求,這觸發了速率限制。 所以我最終得到了接受的答案和@karthik 建議的組合 - 在 request.context 中使用加載器

從 CRA 2.0 開始,包含 @svgr 以將 svg 作為反應組件導入。

const reqSvgs = require.context('!@svgr/webpack!flag-icon-css/flags/4x3', true, /\.svg$/)

所以這里我們結合了一個 svg loader 和 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 包含在 bundle 中,沒有單獨的 http 請求 🎊🎉

您可以使用單個 SVG 精靈代替多個 SVG 文件。

可以使用svg-sprite-generator從 SVG 文件目錄生成 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 )

您可以簡單地創建一個函數,該函數接受一個參數“名稱”(您的 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>
  )
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM