vue引入svg图标

以下操作参照了 RuoYi-Vue

点击下载图标

1、安装fontawesome

npm install font-awesome --save

2、在assets目录下创建以下目录结构,

20200727200430814

其中,svg中存放所有要用到的图标

20200727200444365

index.js中添加以下代码

import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'

Vue.component('svg-icon', SvgIcon)

const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)

3、在vue.config.js添加以下配置

const path = require('path')

function resolve(dir) {
  return path.join(__dirname, dir)
}


module.exports = {
  lintOnSave: false,

  configureWebpack: {
    name: 'icon',
    resolve: {
      alias: {
        '@': resolve('src'),
        'views': resolve('src/views')
      }
    }
  },

  chainWebpack(config) {

    config.module
      .rule('svg')
      .exclude.add(resolve('src/assets/icons'))
      .end()
    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/assets/icons'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })
      .end()
  }
}

20200727200507328

4、在components创建SvgIcon
20200727200525638

index.vue

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

<script>
export default {
  props: {
    iconClass: {
      type: String,
      required: false
    },
    className: {
      type: String,
      default: ""
    }
  },
  computed: {
    iconName() {
      return `#icon-${this.iconClass}`;
    },
    svgClass() {
      if (this.className) {
        return "svg-icon " + this.className;
      } else {
        return "svg-icon";
      }
    },
  }
};
</script>
<style  lang="less" scoped>
.svg-icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
  content: "\e798";
}
</style>

5、继续在components创建IconSelect

20200727200552438

index.vue

<template>
  <div class="icon-body">
    <div class="icon-list">
      <div v-for="(item, index) in iconList" :key="index" @click="selectedIcon(item)">
        <svg-icon :icon-class="item" style="height: 30px;width: 16px;"/>
        <span>{{ item }}</span>
      </div>
    </div>
  </div>
</template>

<script>
import icons from "./requireIcons";
export default {
  data() {
    return {
      name: "",
      iconList: icons
    };
  },
  methods: {
    filterIcons() {
      this.iconList = icons;
      if (this.name) {
        this.iconList = this.iconList.filter(item => item.includes(this.name));
      }
    },
    selectedIcon(name) {
      this.$emit("selected", name);
      document.body.click();
    },
    reset() {
      this.name = "";
      this.iconList = icons;
    }
  }
};
</script>

<style  lang="less" scoped>
.icon-body {
  width: 100%;
  padding: 10px;
  .icon-list {
    height: 200px;
    overflow-y: scroll;
    div {
      height: 30px;
      line-height: 30px;
      margin-bottom: -5px;
      cursor: pointer;
      width: 33%;
      float: left;
    }
    span {
      display: inline-block;
      vertical-align: -0.15em;
      fill: currentColor;
      overflow: hidden;
    }
  }
}
</style>

requireIcons.js

const req = require.context('../../assets/icons/svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys()

const re = /\.\/(.*)\.svg/

const icons = requireAll(req).map(i => {
  return i.match(re)[1]
})

export default icons

6、在main.js中引入icons

import '@/assets/icons' 

7、

  • 可以使用<svg-icon icon-class='name'/>直接在页面显示图标,其中name为.svg文件的文件名

具体效果:20200727200619598

  • 使用IconSelect组件

1、引入IconSelect组件

import IconSelect from "@/components/IconSelect"; 
export default {
  components: { IconSelect },
  data() {
    return {
      icon: ""
    };
  },
}

2、页面使用

<IconSelect ref="iconSelect" @selected="selected"/>
<el-input slot="reference" v-model="icon" placeholder="点击选择图标" readonly>
<svg-icon slot="prefix" :icon-class="icon" style="height: 32px;width: 16px;"/>

具体效果
20200727200635358

posted @ 2020-07-27 20:09  神无二一  阅读(963)  评论(5编辑  收藏  举报