Skip to content

Instantly share code, notes, and snippets.

@lesonky
Last active May 23, 2024 03:46
Show Gist options
  • Save lesonky/d8222493c7e2add2e7dd1942f92ed5ae to your computer and use it in GitHub Desktop.
Save lesonky/d8222493c7e2add2e7dd1942f92ed5ae to your computer and use it in GitHub Desktop.
如何将 iconfont 融入 vuetify #iconfont #vuetify

前言: vuetify 为我们提供了很多 iconfont 选择,并且提供了一个 VIcon 的组件,使用还是比较方便的,但是随着需求的不断迭代,公版的 iconfont 已经不足以满足我们的需求,我们需要一个自己定制一些 icon,那么问题就来了,如果让自定义的icon和原有的 VIcon 组件结合呢,毕竟提供两种 icon 组件会在使用的时候感到困惑.

解决问题:

根据 vuetify 的文档,我们找到最后一段

// Instead of provided icon fonts presets you can use your own component icons. You also can switch icons that are used in Vuetify component with your own.

import Vue from 'vue'
import Vuetify from 'vuetify'
import IconComponent from './IconComponent.vue'

Vue.use(Vuetify, {
  icons: {
    'product': {
      component: IconComponent, // you can use string here if component is registered globally
      props: { // pass props to your component if needed
        name: 'product'
      }
    }
  }
})

这就是解决这个问题的钥匙了,我们只要把自定义的icon通过这种方式注册一下,在使用的时候使用 $vuetify.icons.youriconname 的形式,就可以通过VIcon组件调用到我们自己的icon组件.

接下来,我们要解决的就是如果制作我们自己的icon组件了,首先参考iconfont使用文档 , 我们使用iconfont.js的方式来使用iconfont图标,而不是通过font的形式来使用,因为iconfont.js的形式是讲图标的 svg 写入页面,然后通过 svg 的引用来实现图标的,文档如下:

第一步:拷贝项目下面生成的symbol代码:

//at.alicdn.com/t/font_8d5l8fzk5b87iudi.js

第二步:加入通用css代码(引入一次就行):

<style type="text/css">
    .icon {
       width: 1em; height: 1em;
       vertical-align: -0.15em;
       fill: currentColor;
       overflow: hidden;
    }
</style>

第三步:挑选相应图标并获取类名,应用于页面:

<svg class="icon" aria-hidden="true">
    <use xlink:href="#icon-xxx"></use>
</svg>

我们将第三步翻译成 vue 组件

<template>
  <svg :class="svgClass" aria-hidden="true" v-on="$listeners">
    <use :xlink:href="iconName"/>
  </svg>
</template>

<script>
export default {
  name: 'SvgIcon',
  props: {
    iconClass: {
      type: String,
      required: true,
    },
    className: {
      type: String,
      default: '',
    },
  },
  computed: {
    iconName() {
      return `#icon${this.iconClass}`;
    },
    svgClass() {
      if (this.className) {
        return `svg-icon ${this.className}`;
      }
      return 'svg-icon';
    },
  },
};
</script>

<style scoped>
.svg-icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}
</style>

然后再将iconfont有关的代码组织起来

import '@/assets/iconfont/iconfont.js';
import SvgIcon from '@/components/SvgIcon';
import Vue from 'vue';

// register globally
Vue.component('svg-icon', SvgIcon);

// 这里是需要注册的组件名称
const Icons = [
  'shangsheng',
  'xiajiang',
  'logo',
  'caidanzhankai',
  'caidanshou',
  'gengxin',
  'shunshizhen',
  'rili',
  'quanping',
  'shuoming',
  'nishizhen',
  'sousuo',
  'shezhi',
  'wenjianjia',
  'tubiao',
  'arrowshang',
  'wenjianjiadakai',
  'arrowxia',
  'shaixuan',
];

const IconFont = Icons.reduce((ret, icon) => {
  ret[icon] = {
    component: SvgIcon,
    props: {
      iconClass: icon,
      className: icon,
    },
  };
  return ret;
}, {});

export default IconFont;

最后在 入口文件(一般是main.js)中引用一下

// ... 省略了其他代码
import IconFont from '@/icons';

// ... 省略了其他代码

// 注册自定义 iconfont 不用 cdn 的时候可以用这个方式
Vue.use(Vuetify, {
  icons: IconFont,
});

// 如果使用 cdn 来加载 vuetify,install 方法是没有用的,这个时候,我们可以手动挂载一下
Vue.prototype.$vuetify.icons = { ...Vue.prototype.$vuetify.icons, ...IconFont };

使用示例:

<!-- for example, your icon name is myiconname -->
<v-icon v-text="$vuetify.icons.myiconname"/>
@kvii
Copy link

kvii commented Mar 27, 2021

到现在(2021年3月28日)为止,google 上只能搜到这一篇比较完整的教程。
感谢大佬提供的代码示例。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment