基于Typescript的Vue项目中使用svg图标

简介

vue-cli2.x搭建的vue项目中使用svg图标参考:Vue项目常见问题-项目中使用svg图标

vue-cli3.x搭建的vue项目中使用svg图标思路相同,方法基本类似。以下是详细步骤

步骤

  • 安装svg-sprite-loadernpm i svg-sprite-loader --save-dev
  • src/目录下新建目录icons/,用来放置图标相关文件
  • src/icons/目录下新建svg/目录,用来放置svg/图标文件
  • src/components/目录下新建文件svgIcon.vue
<template> <svg :class="svgClass" aria-hidden="true" v-on="$listeners"> <use :xlink:href="iconName" /> </svg> </template> <script lang="ts"> import { Component, Vue, Prop } from 'vue-property-decorator'; @Component export default class SvgIcon extends Vue { @Prop({ default: '', type: String }) private iconClass!: string; @Prop({ default: '', type: String }) private className!: string; private get iconName() { return `#icon-${this.iconClass}` } private get svgClass() { if (this.className) { return 'svg-icon ' + this.className; } else { return 'svg-icon'; } } } </script> <style scoped> .svg-icon { width: 1em; height: 1em; vertical-align: -0.15em; fill: currentColor; overflow: hidden; } </style>
  • src/icons/目录下新建文件index.ts
// 引入 icon 组件并全局注册 // 实现自动引入 @/src/icons 下面所有的图标 // require.context("./test", false, /.test.js$/); 这行代码就会去 test 文件夹(不包含子目录)下面的找所有文件名以 .test.js 结尾的文件能被 require 的文件。 // 更直白的说就是 我们可以通过正则匹配引入相应的文件模块 // require.context 的三个参数: // directory:说明需要检索的目录 // useSubdirectories:是否检索子目录 // regExp: 匹配文件的正则表达式 import Vue from 'vue' import SvgIcon from 'components/svgIcon.vue'// svg组件 // register globally Vue.component('svg-icon', SvgIcon) const req = require.context('./svg', false, /\.svg$/) const requireAll = (requireContext: any) => requireContext.keys().map(requireContext) requireAll(req)
  • src/main.ts文件中引入
import './icons'
  • 修改vue.config.js文件
// vue-cli默认 webpack-chain 基础 loader 配置参考:https://github.com/vuejs/vue-cli/blob/dev/packages/%40vue/cli-service/lib/config/base.js // vue-cli默认情况下会使用 file-loader 对svg 进行处理,会将它放在/img 目录下 // webpackConfig.module // .rule('svg') // .test(/\.(svg)(\?.*)?$/) // .use('file-loader') // .loader(require.resolve('file-loader')) // .options({ // name: genAssetSubPath('img') // }) const path = require('path') function resolve (dir) { return path.join(__dirname, dir) } module.exports = { // ... chainWebpack: config => { // ... // 方法一:去掉默认的svg处理 // 不能保证所有的 svg 都是用来当做 icon的,有些真的可能只是用来当做图片资源的 // 不能确保你使用的一些第三方类库会使用到 svg // 不推荐这种做法 // config.module // .rule('svg') // .uses.clear() // // config.module.rules.delete('svg') // config.module // .rule('svg1') // .test(/\.svg$/) // .use('svg-sprite') // .loader('svg-sprite-loader') // .options({ // symbolId: 'icon-[name]' // }) // .end() // .include // .add(resolve('src/icons')) // .end() // 方法二:使用 webpack 的 exclude 和 include // 让 svg-sprite-loader 只处理你指定文件夹下面的 svg, // file-loaer 只处理除此文件夹之外的所有 svg config.module .rule('svg') .exclude .add(resolve('src/icons')) .end() config.module .rule('svg1') .test(/\.svg$/) .use('svg-sprite') .loader('svg-sprite-loader') .options({ symbolId: 'icon-[name]' }) .end() .include .add(resolve('src/icons')) .end() // ... } }
  • vue组件中使用
<svg-icon icon-class="article" />

备注:article为图标文件的文件名


创作不易,若本文对你有帮助,欢迎打赏支持作者!

 分享给好友: