如何在Vuetify中添加自定义SVG图标 - Vue

29

我正在使用vuetify 1.1.8和vue 3.0.0-rc.3。我尝试在我的项目中使用一些自定义的SVG图标,而不是由vuetify支持的Material Icons或FontAwesome Icons默认图标。

我尝试使用vue-svg-loader加载我的自定义SVG图标,并将它们用作组件。像这样:

<template>
    <icon-one></icon-one>
</template>

<script>
    import iconOne from './public/iconOne.svg'
    export default{
        components:{
                 iconOne
          }
    }
</script>

然而问题在于vue-svg-loader无法在<v-text-field>append-icon和许多其他我可以使用<v-icon>的地方使用它们。

我也阅读了vuetify文档,其中提到了使用自定义图标,但我认为这并没有帮助。

有人能帮我解决这个问题吗?也许我应该尝试使用material angular支持的sprite-images。

TL;DR

我有自定义的SVG图标,并且想要将它们作为<v-icon>customIcon</v-icon>在vuetify中使用。


有什么阻止您只使用标准的图像标记并使用css适当地调整大小?或者手动将其包装在组件中以便重复使用,这基本上不会改变太多,而且也不会很麻烦。 - li x
2
img标签很烦人。特别是当你想要将图标与字体大小相同并位于其左侧或右侧时。就像你想要使用图标作为span标签一样。 - user2912903
6个回答

48

根据vuetify v2的文档,创建一个包含SVG图标代码的自定义组件。

// CustomIcon.vue
<template>
  <svg>
    ...
  </svg>
</template>

vuetify的配置中包含自定义图标组件:

// vuetify.ts

import CustomIcon from '@/components/CustomIcon.vue'

export default new Vuetify({
  theme: {/**/},
  icons: {
    values: {
      custom: { // name of our custom icon
        component: CustomIcon, // our custom component
      },
    },
  },
})

如此使用:

<v-icon>$vuetify.icons.custom</v-icon>

或快捷方式:

<v-icon>$custom</v-icon>


1
@GeorgeAlvis,这个解决方案在Nuxt中对我有效: https://codesandbox.io/s/z42mm?file=/pages/index.vue 基本上,您需要将一些Vuetify选项移动到一个文件中,通过Vuetify的optionsPath导入,以便您可以将Vue图标组件导入到该Vuetify选项文件中。 - samnau
2
我尝试过这个,但不知何故没有任何显示和错误出现。 - Otorrinolaringologista -man
@Otorrinolaringologista-man 嗯,可能是 SVG 文件有问题?我也遇到过这种情况... 除此之外没有其他想法,可能要确保没有打错字,并且要确保文件结构正确。 - Traxo
2
这似乎不再起作用了。我本地的尝试得到了与@samnau发布的沙箱显示的相同错误。 - Bonteq
我也不行。 - Simon

24
你确实可以在其自己的Vue单文件组件内创建一个Vue图标,然后注册此组件,以便vuetify可以在VICon(v-icon)组件内使用它。
要创建Vue组件图标,您只需要像Vue Cookbook中所示,在模板标记中放置SVG即可。本文档应帮助您在任何vue应用程序中使用该组件。
<template>
    <svg>...</svg>
</template>

接下来,您需要在vuetify中注册此组件。Vuetify的配置有时会在索引文件中,或者在现代vue-cli中,它将在@/src/plugins/vuetify.js中找到。

在那里,您可以像Vuetify网站上显示的那样注册您的组件(您已经提到了此链接),但是也许这份文档是一个更新版本或不太清楚。

现在,该组件将被注册并可以在VApp内的任何地方使用。但是,与标准图标不同,您需要在v-icon的插槽中使用$vuetify.icons.[icon-name]。在Vuetify示例中,该图标被注册为“product”。要使用它,您需要包括

<v-icon>$vuetify.icons.product</v-icon>

我在一个正在进行的项目中实现了这个功能。我会留下当前状态的分支这里

图标组件位于/src/icons。Vuetify配置位于/src/plugins,svg图标组件位于/src/components/PlotSelector.vue。


2

这是我的Nuxt最终解决方案,但您可以将其应用于纯Vue.js:

npm i '@nuxtjs/svg' -D

nuxt.config.js:

buildModules: [
  '@nuxtjs/svg'
],
vuetify: {
  customVariables: ['~/assets/variables.scss'],
  treeShake: true,
  optionsPath: './vuetify.config.js'
},

vuetify.config.js

icons: {
  iconfont: 'mdi',
  values: {
    chat: {
      component: require('~/assets/img/icons/chat.svg?inline')
    }
  }
}

聊天.svg(别忘了设置:fill="currentColor")

<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
  <path d="M16.5569 3H3.44278C2.09549 3 1 4.09596 1 5.44313V13.1331C1 14.4802 2.09549 15.5762 3.44278 15.5762H13.3415L15.4019 18.0107C15.4723 18.0944 15.5757 18.1402 15.6816 18.1402C15.7238 18.1402 15.766 18.1323 15.8075 18.1173C15.952 18.0643 16.0478 17.927 16.0478 17.7739V15.5761H16.5572C17.9043 15.5761 19 14.4802 19 13.133V5.44313C18.9997 4.09596 17.9044 3 16.5569 3ZM7.18042 10.2514C6.7072 10.2514 6.32357 9.86785 6.32357 9.39499C6.32357 8.92141 6.7072 8.53796 7.18042 8.53796C7.65328 8.53796 8.03709 8.92141 8.03709 9.39499C8.03709 9.86791 7.65328 10.2514 7.18042 10.2514ZM9.99967 10.2514C9.52645 10.2514 9.143 9.86785 9.143 9.39499C9.143 8.92141 9.52645 8.53796 9.99967 8.53796C10.4725 8.53796 10.8562 8.92141 10.8562 9.39499C10.8562 9.86791 10.4725 10.2514 9.99967 10.2514ZM12.9953 10.2514C12.522 10.2514 12.1382 9.86785 12.1382 9.39499C12.1382 8.92141 12.522 8.53796 12.9953 8.53796C13.4681 8.53796 13.852 8.92141 13.852 9.39499C13.852 9.86791 13.4681 10.2514 12.9953 10.2514Z" fill="currentColor"/>
</svg>

任何组件:

<v-icon>$chat</v-icon>

希望这能帮助各位。

这似乎覆盖了主题。背景突然变成白色。 - Lara

0
依赖项:
- vue: "^3.x" - vuetify: "^3.x" - vite: "^4.x"
添加Vite SVG Loader
npm i -D vite-svg-loader

给Vuetify配置添加别名
// plugins/vuetify.ts

import settings from '@/assets/icons/settings.svg'; // <- custom icon

import { IconAliases, createVuetify } from 'vuetify';
import { aliases as defaultAliases } from 'vuetify/iconsets/mdi';

const aliases: IconAliases = {
  ...defaultAliases,
  settings,
};

export default createVuetify({
  icons: {
    aliases,
  },
});

在模板中使用图标名称时,前缀为$
<v-btn icon="$settings"></v-btn>

0

对于 Vuetify 和 Nuxt,您可以这样做:

将您的标志文件放入静态文件夹中,并在组件文件夹中创建 CompanyLogo.vue

<template>
  <img src="/company-logo.svg">
</template>

然后您可以通过<CompanyLogo />在其他每个组件中使用它

如果您想要,您还可以对其进行动画处理,例如:

<template>
  <img
    class="LogoAnimation"
    src="/company-logo.svg"
  >
</template>

<style>
.LogoAnimation {
  transform: rotateY(560deg);
  animation: turn 3.5s ease-out forwards 1s;
}

@keyframes turn {
  100% {
    transform: rotateY(0deg);
  }
}
</style>

5
OP特别询问<v-icon>,而不仅仅是显示SVG。 - benjymous

0
你还可以创建一个使用mask来应用SVG图形的CSS class
例如,在我的实现中,我在global.css中有这个class,它被导入到main.ts中,意味着在整个应用程序中都可用。
.some-icon {
  background-color: #f69e01;
  -webkit-mask: url(@/assets/someLogo.svg) no-repeat center;
  mask: url(@/assets/someLogo.svg) no-repeat center;
}

然后,在任何模板中,可以通过将自定义类添加到<v-icon>元素来使用它。
<v-icon class="some-icon" />

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