简介
vue-cli2.x
搭建的vue
项目中使用svg
图标参考:Vue项目常见问题-项目中使用svg图标
vue-cli3.x
搭建的vue
项目中使用svg
图标思路相同,方法基本类似。以下是详细步骤
步骤
- 安装
svg-sprite-loader
:npm 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
为图标文件的文件名
发表评论