背景
一般html中使用svg图片是用img标签使用,这在项目中就相对来说非常麻烦。出现大量使用svg情况就变的比较麻烦
<img src="../assets/svgs/car.svg" />
封装
将svg文件统一放一个文件夹下 src/assets/svgs
需要2步
为文件打包
安装开发依赖
npm i svg-sprite-loader -D
打包配置
....
chainWebpack: config => {
config.module
.rule('svg')
.exclude.add(resolve('src/assets/svgs'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/assets/svgs'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
},
....
或
...
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
chainWebpack: (config) => {
const svgRule = config.module.rule('svg')
svgRule.uses.clear()
// 添加要替换的 loader
svgRule.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({symbolId: 'icon-[name]'})
}
})
...
为开发
封装VSvg.vue
<template>
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
<use :xlink:href="iconName" />
</svg>
</template>
<script>
import { isExternal, importAll } from '@/utils/util'
importAll(require.context('@/assets/svgs', false, /\.svg$/))
export default {
name: 'VSvg',
props: {
icon: {
type: String,
required: true
},
className: {
type: String,
default: ''
}
},
computed: {
isExternal () {
return isExternal(this.icon)
},
iconName () {
return `#icon-${this.icon}`
},
svgClass () {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
},
styleExternalIcon () {
return {
mask: `url(${this.icon}) no-repeat 50% 50%`,
'-webkit-mask': `url(${this.icon}) no-repeat 50% 50%`
}
}
}
}
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.svg-external-icon {
background-color: currentColor;
mask-size: cover !important;
display: inline-block;
}
</style>
util.js
export function isExternal (path) {
return /^(https?:|mailto:|tel:)/.test(path)
}
export function importAll (requireContext) {
requireContext.keys().forEach(requireContext)
}
关于require.context方法
核心就是使用了webpack内置的require.context方法
详细参数解释点击这里官网传送门
require.context(
directory, //这里指存放svg文件目录的路径
(useSubdirectories = true), //是否还搜索其子目录,默认为true
(regExp = /^\.\/.*$/), //正则匹配文件类型, 这里我们匹配 .svg 结尾的文件 /\.svg$/
(mode = 'sync') //模式,默认同步
);
main中注册文章来源:https://www.toymoban.com/news/detail-717480.html
import VSvg from '@/components/base/VSvg.vue'
import Vue from 'vue'
Vue.component('v-svg', VSvg)
由于此处我注册的组件较多,而且都在一个文件里面文章来源地址https://www.toymoban.com/news/detail-717480.html
const registerGlobal = (Vue) => {
const requireComponent = require.context(
'@/components/base', true, /\.vue$/
)
console.log('学习', requireComponent)
requireComponent.keys().forEach(fileName => {
const componentConfig = requireComponent(fileName)
const Component = componentConfig.default || componentConfig
const componentName = kebabCase(fileName.replace(/^\.\//, '').replace(/\.\w+$/, ''))
if (typeof Component.install === 'function') {
Vue.use(Component)
} else {
Vue.component(componentName, Component)
}
})
Vue.directive('perm', hasPerm)
Vue.filter('dayjs', (val, formatter = 'YYYY-MM-DD HH:MM:ss') => dayjs(val).format(formatter))
}
组件使用
<v-svg icon="zoom-out" />
到了这里,关于vue项目中使用svg的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!