如何通过vue-svg-loader在Vue.js中导入多个SVG?

5
我希望在一个vue组件中导入多个svg。文档说我必须导入它们中的每一个,但是如何以更短、更干净的方式导入多个svg呢?请参考vue-svg-loader文档:https://vue-svg-loader.js.org/
<script>
import Info from "@/assets/svgs/info.svg";
import Help from "@/assets/svgs/help.svg";
import Close from "@/assets/svgs/close.svg";
// etc. pp.

export default {
  components: {
    Info,
    Help,
    Close
  }
</script>

如果我有超过一百个SVG文件需要导入,会发生什么?

有什么解决方法吗?


你能把它们嵌入一个巨大的XML文件中吗? - Mr. Polywhirl
2个回答

10

创建一个基础组件并全局注册,因为您将非常频繁地使用它。


创建一个<BaseIcon>组件,使用require表达式来创建SVG模块的上下文。
<template>
  <Component
     :is="require(`@/assets/svgs/${name}.svg`).default"
     class="BaseIcon"
     v-bind="$attrs"
     @v-on="$listeners"
  />
</template>

<script>
export default {
  name: 'BaseIcon',

  // Transparent wrapper component
  // https://v2.vuejs.org/v2/guide/components-props.html#Disabling-Attribute-Inheritance
  inheritAttrs: false,
  
  props: {
    name: {
      type: String,
      required: true,
    },
  },
}
</script>

<style>
 .BaseIcon {
   /* Add some default CSS declaration blocks */
 }
 </style>

注意:我们使用<Component>来处理动态组件,这假定您将使用vue-svg-loader且SVG将被视为组件。如果不是这种情况,请改用<img>标签,并使用src而不是is

全局注册基础组件:

如果您只创建了一个基础组件,可以在挂载应用程序之前转到您的main.js文件并执行以下操作:

import Vue from 'vue'
import BaseIcon from './components/_base/BaseIcon.vue'
import App from './App.vue'

Vue.component('BaseIcon', BaseIcon)

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

如果你想要更复杂的东西,可以看看这个样板自动注册基础组件


最后,像这样使用{{组件}}:
<template>
  <div>
    <BaseIcon
      name="info"
    />
    <BaseIcon
      name="help"
    />
    <BaseIcon
      name="close"
    />
  </div>
</template>

<script>
export default {
  name: 'SomeComp',
}
</script>

嗨@Ricky,非常感谢 - 看起来非常准确。我创建了BaseIcon组件,并在main.js中全局添加了它,然后通过<BaseIcon name="search" />实现。但是我遇到了一个错误:无法挂载组件:未定义模板或渲染函数。有什么想法吗? - wittgenstein
使用以下代码进行修复::is="require(@/assets/svgs/${name}.svg).default" - wittgenstein
1
@wittgenstein Chris在这里解释了为什么需要根据模块的导入方式使用default链接 - Ricky Ruiz

0

不幸的是,this answer 中描述的方法在我的情况下没有起作用(Vue-CLI 3 + Vue 2)。

示例: 外部SVG:

    <img :src="require(`@/assets/img/icons/base/config.svg`).default" />

内联 SVG(动态组件):

    <component :is="require(`@/assets/img/icons/base/config.svg?inline`)" />

内联 SVG(组件):

<template><config-icon /></template>
import ConfigIcon from '@/components/icons/config-icon.vue';

请将以下代码添加到 vue.config.js 文件中:
      chainWebpack: (config) => {
       const svgRule = config.module.rule('svg');

       svgRule.uses.clear();
       svgRule.delete('type');
       svgRule.delete('generator');

       svgRule
        .oneOf('inline')
        .resourceQuery(/inline/)
        .use('babel-loader')
        .loader('babel-loader')
        .end()
        .use('vue-svg-loader')
        .loader('vue-svg-loader')
        .end()
        .end()
        .oneOf('external')
        .use('file-loader')
        .loader('file-loader')
        .options({
          name: 'assets/[name].[hash:8].[ext]',
        });
      },

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接