如何将 svg 文件导入 Vue 组件?

Posted

技术标签:

【中文标题】如何将 svg 文件导入 Vue 组件?【英文标题】:How can I import a svg file to a Vue component? 【发布时间】:2017-11-25 12:09:24 【问题描述】:

在 vue 单个文件组件中。我导入一个 svg 文件,如下所示: import A from 'a.svg' 那么如何在我的组件中使用 A 呢?

【问题讨论】:

你需要它做什么?这里缺少大量信息 这个问题不是 Vue 特定的,因为它取决于你用来加载 SVG 文件的 webpack 加载器。你想用那个 import 语句实现什么?您是否希望 A 成为包含您的 SVG 文件的字符串?您想在模板中内联还是简单地包含a.svg?您是否只想确保在插入组件时a.svg 可用?请用用例、Vue 组件的相关部分以及 webpack 配置的相关部分扩展您的问题。 不仅不是 Vue 特定的,也不是 Webpack 特定的...... 【参考方案1】:

你也可以这样使用:

<template>
  <img :src="logo"></img>
</template>

<script>
import logo from '../assets/img/logo.svg'

export default 
  data() 
    return 
      logo
    
  

</script>

这不需要安装外部模块并且开箱即用。

【讨论】:

请注意,如果将 svg(填充/描边)用作图像 src,则不能影响其属性。 ***.com/questions/44695560/… 没错,但有些人只是需要这个。我只是需要这个。【参考方案2】:

为@Stephan-v's solution +1,但这是针对 2021 年使用 Webpack 5 稍作修改的方法。

    你的 Vue 组件&lt;template/&gt;

选项 A:单个 SVG 文件

<template>
  <svg viewBox="0 0 24 24">
    <use :xlink:href="require('@/assets/icons/icon.svg')"></use>
  </svg>
</template>

选项 B:SVG Sprite(例如,用于 FeatherIcons)

<template>
  <svg viewBox="0 0 24 24">
    <use
      :xlink:href="require('@/assets/icons/sprite.svg') + `#$iconName`"
    ></use>
  </svg>
</template>

<script>
export default 
  props: 
    // Dynamic property to easily switch out the SVG which will be used
    iconName: 
      type: String,
      default: "star",
    ,
  ,
;
</script>
    您可能需要一个 Webpack 加载器。

注意:如果您使用的是 Vue 3(如上所述)或 Vite,则可能不需要 Webpack Loader。如果您使用的是 Storybook 或 Nuxt,您可能仍然需要它。

$ npm install svgo-loader -D
$ yarn add svgo-loader -D

webpack.config.js(或类似)

module.exports = 
  mode: "development",
  entry: "./foo.js",
  output: ,
  // ... other config ...
  module: 
    rules: [
      /////////////
      
        // Webpack 5 SVG loader
        // https://webpack.js.org/guides/asset-modules/
        // https://dev.to/smelukov/webpack-5-asset-modules-2o3h
        test: /\.svg$/,
        type: "asset",
        use: "svgo-loader",
      ,
    ],
    /////////////
  ,
;
    完成!

【讨论】:

【参考方案3】:

我喜欢使用 pug 作为模板引擎(有很多优点)——如果你这样做了,你将能够轻松地通过编写来包含像 SVG 这样的文件:

include ../assets/some-icon.svg

就是这样!没有别的事可做 - 我认为这是一种非常简单方便的方法来包含较小的 svg 之类的东西 - 文件容易包含的代码仍然很干净!

在这里您可以获得更多信息,了解如何将 PugJS 包含到您的 Vue 实例中 https://www.npmjs.com/package/vue-cli-plugin-pug

【讨论】:

你会把它放在哪里?我很困惑,因为它看起来像是 javascript 的一部分......但如果是这种情况,你还没有显示 pug 标记? 看看 PugJS 文档,那里记录了如何做到这一点:pugjs.org/language/includes.html【参考方案4】:

我只会使用vue-svg

通过 Vue CLI 3 安装

vue add svg

输入:

<img src="@/assets/logo.svg?data" />

输出:

<img src="data:image/svg+xml;base64,..." />

或者这也是工作......

import LogoImage from "@/assets/logo.svg?inline"

【讨论】:

【参考方案5】:

我已经在 Vue 3 中完成了以下工作。不需要搞乱 webpack 或安装任何第三方插件。

<template>
  <img :src="mySVG" />
</template>

<script>
export default 
  name: 'App',
  data()
    return 
      mySVG: require('./assets/my-svg-file.svg')
    
  

</script>

注意:我知道在 img src 中使用 SVG 时,您无法修改某些部分,但如果您只是想像使用任何其他图像一样使用 SVG 文件,这似乎成为一个快速简便的解决方案。

【讨论】:

如果您想按原样使用图像 - 那么您甚至根本不需要它。只需&lt;img src="@/assets/my-svg-file.svg" /&gt;【参考方案6】:

首先,您需要一个特定的加载器来加载包含 svg 的组件 我的 webpack.base.config.js

module: 
    rules: [
      
        test: /\.svg$/,
        loader: 'vue-svg-loader',
      ,
      
        test: /\.vue$/,

        use: [
                    
            loader: "vue-loader", 
            options: vueLoaderConfig
                    ,
                    
                        loader: "vue-svg-inline-loader",
                        options:  /* ... */ 
                    
                ]
      
//.. your other rules

vues-svg-inline-loader 的文档:https://www.npmjs.com/package/vue-svg-inline-loader vue-svg-loader 文档:https://www.npmjs.com/package/vue-svg-loader

接下来可以初始化一个vue文件

<template>
<div>

  <img svg-inline class="icon" src='../pathtoyourfile/yoursvgfile.svg'  />

</div>
</template>

<script>
import axios from 'axios'



export default 
  name: 'logo',
  data () 
  ,
  

</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
#logo
  width:20%;

.rounded-card
    border-radius:15px;

//the style of your svg 
//look for it in your svg file ..
//example
.cls-1,.cls-7isolation:isolate;.cls-2fill:url(#linear-gradient);.cls-3fill:url(#linear-gradient-2);;stroke-width:2px;..cls-6opacity:0.75;mix-blend-mode:multiply;.cls-7opacity:0.13;.cls-8fill:#ed6a29;.cls-9fill:#e2522b;.cls-10fill:#ed956e;.cls-185fill:#ffc933;..cls-13fill:#ffd56e;.cls-14fill:#1db4d8;.cls-15fill:#0f9fb7;.cls-16fill:#3ad4ed;.cls-17fill:#25bdde;.cls-18fill:#fff;
//


</style>


您的 svg 文件必须不包含样式标签,因此请复制粘贴带有作用域属性的 vue 样式中的样式,以使其特定于该组件 您可以将组件加载到应用程序的特定位置 并使用它

<template>

<v-app id="app">

    <logo/>
   <router-view/>

</v-app>



</template>

<script>
import logo from './components/logo.vue'

export default 
  name: 'App',
  data()
    return 
      //your data
    
  ,
  components:
logo //the name of the component you imported
  ,


  

</script>

<style>
#app 

  font-family: 'Hellow', sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #070b0f;
  margin-top: 60px;


</style>

【讨论】:

【参考方案7】:

如果您使用 Webpack,您可以使用 require 上下文从目录加载 SVG 文件。请注意,这会将所有 SVG 文件放入您的 Javascript 文件中,但可能会使您的代码膨胀。

作为一个简化的例子,我正在使用这个svg 组件:

data() 
    return 
        svg: ''
    ;
,

props: 
    name: 
        type: String,
        required: true
    


created() 
    this.svg = require(`resources/assets/images/svg/$this.name.svg`);

模板看起来像这样:

<template>
    <div :class="classes" v-html="svg"></div>
</template>

通常你不能像这样简单地加载 SVG 文件并期望它们与 v-html 指令一起使用,因为你没有得到原始输出。您必须使用 Webpack raw-loader,因此请确保获得原始输出:


    test: /\.svg$/,
    use: [
        
            loader: 'raw-loader',
            query: 
                name: 'images/svg/[name].[ext]'
            
        ,
        
            loader: 'svgo-loader',
            options: svgoConfig
        
    ]

上面的例子也使用了svgo-loader,因为如果你这样做的话,你会想要大量优化你的 SVG 文件。

希望这可以帮助您或其他任何人了解如何解决此问题,而无需直接使用第三方解决方案来解决此问题。

【讨论】:

【参考方案8】:

您始终可以将其保存为/static/svg/myfile.svg 中的 .svg 文件(使用 webpack),然后将其用作图像文件:&lt;img src="/static/svg/myfile.svg"&gt;。不需要 require / import / loader。

【讨论】:

如果你想用 css 类或fill:currentColor 与 SVG 进行交互,则不起作用@【参考方案9】:

如果您可以控制 svg 文件,则可以将其包装在 vue 文件中,如下所示:

a.vue:

<template>
  <svg>...</svg>
</template>

之后只需要这样的文件:import A from 'a.vue'

【讨论】:

这种方法有什么缺点,除了如果你有很多 SVG 就必须包装每个 SVG 吗? 如果你有很多 svg 文件,你应该像@renato-krcelic 建议的那样使用加载器“正确”加载它们。【参考方案10】:

根据您提供的信息,您可以做的是:

    安装 vue-svg-loader

npm install --save-dev vue-svg-loader

    配置 webpack:

module: 
    rules: [
      
       test: /\.svg$/,
       loader: 'vue-svg-loader', // `vue-svg` for webpack 1.x
      ,
    ],
  ,
    导入 svg 并将其用作常规组件:

<template>
  <nav id="menu">
    <a href="...">
      <SomeIcon class="icon" />
      Some page
    </a>
  </nav>
</template>

<script>
import SomeIcon from './assets/some-icon.svg';

export default 
  name: 'menu',
  components: 
    SomeIcon,
  ,
;
</script>

参考:https://github.com/visualfanatic/vue-svg-loader

【讨论】:

这个解决方案非常好。但是,我花了一段时间才弄清楚两件事:1. 如果您使用的是 vue CLI 3.x,您需要创建一个 vue.config.js 文件来修改 webpack 配置,如github.com/visualfanatic/vue-svg-loader#vue-cli 和 2.如果您使用 TypeScript,您还需要声明一个 svg 模块,如文档中所述:github.com/visualfanatic/vue-svg-loader/blob/master/docs/… 很棒的工具 - 使用它但我遇到了 Invalid Component Definition - 但很快在 github.com/visualfanatic/vue-svg-loader/issues/1 中找到了原因 安装一个 npm 包并不能帮助理解它是如何工作的。

以上是关于如何将 svg 文件导入 Vue 组件?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 SVG 导入 Next.js 组件?

如何将 vue 组件导入 laravevel app.js 文件?

将 npm 包导入 Vue.js 单文件组件

如何将函数导入 Vue 组件?

如何在 vue 组件中导入 CSS 文件,范围仅限于组件?

如何将 scss 导入到我的 Vue 组件中?