【问题标题】:How can I import a svg file to a Vue component?如何将 svg 文件导入 Vue 组件?
【发布时间】: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 特定的......

标签: javascript svg vue.js


【解决方案1】:

你也可以这样使用:

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

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

export default {
  data() {
    return {
      logo
    }
  }
}
</script>

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

【讨论】:

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

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

  1. 你的 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>
  1. 您可能需要一个 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",
      },
    ],
    /////////////
  },
};
  1. 完成!

【讨论】:

    【解决方案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' alt="example" />
      
      </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-7{isolation:isolate;}.cls-2{fill:url(#linear-gradient);}.cls-3{fill:url(#linear-gradient-2);};stroke-width:2px;}..cls-6{opacity:0.75;mix-blend-mode:multiply;}.cls-7{opacity:0.13;}.cls-8{fill:#ed6a29;}.cls-9{fill:#e2522b;}.cls-10{fill:#ed956e;}.cls-185{fill:#ffc933;}..cls-13{fill:#ffd56e;}.cls-14{fill:#1db4d8;}.cls-15{fill:#0f9fb7;}.cls-16{fill:#3ad4ed;}.cls-17{fill:#25bdde;}.cls-18{fill:#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】:

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

          1. 安装 vue-svg-loader

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

          1. 配置 webpack:

          module: {
              rules: [
                {
                 test: /\.svg$/,
                 loader: 'vue-svg-loader', // `vue-svg` for webpack 1.x
                },
              ],
            },
          1. 导入 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

          【讨论】:

          猜你喜欢
          • 2021-06-13
          • 2019-07-23
          • 2017-05-18
          • 2019-10-10
          • 2018-08-26
          • 1970-01-01
          • 2019-04-18
          • 2019-04-03
          • 2019-01-17
          相关资源
          最近更新 更多