可参考:
未来必热:SVG Sprites技术介绍
懒人神器:svg-sprite-loader实现自己的Icon组件
在Vue3项目中使用svg-sprite-loader
前置知识
在页面中,虽然可以通过如下的方式使用img标签,来引入svg图标。但是,如果这个路径很长,也是比较麻烦的。
<img src="./svg/icon.svg" />
在svg里面,可以在文档中先定义Symbol,然后svg使用的时候,只须通过标识去引用指定的svg即可,Symbol的放置顺序不一定要在最前面,案例如下:
<html>
<head>
<meta charset="utf-8">
<title>SVG Sprite使用</title>
<style>
li {
font-size: 14px;
margin-top: 5px;
color: #369;
}
.webicon {
width: 16px;
height: 16px;
margin-right: 5px;
vertical-align: -2px;
fill: #369;
}
</style>
</head>
<body>
<div style="display: none;"><svg>
<symbol id="liwu" viewBox="-80 -72.013 160 144.025">
<path
d="M-71.949-16.039h55.974v-55.974h-55.974V-16.039z M16.102-16.039h55.975v-55.974H16.102V-16.039z M-80,32.013h64.025v-40H-80V32.013z M80,32.013v-40H16.102v40H80z M-7.923,32.013H8.051V-72.013H-7.923V32.013z M16.102,39.936 h-32.077v24.025h32.077V39.936z M64.025,39.936h-40l15.719,32.077h24.281V39.936z M-23.898,39.936h-40v32.077H-40L-23.898,39.936z"
transform="matrix(1 0 0 -1 0 0)"></path>
</symbol>
<symbol id="qianbi" viewBox="-79.5 -79.5 159 159">
<path
d="M79.5,32.802l-93.538-93.538l-46.699,46.699L32.802,79.5L79.5,32.802z M-79.5-32.802L-32.802-79.5H-79.5 V-32.802z"
transform="matrix(1 0 0 -1 0 0)"></path>
</symbol>
<symbol id="shangchuan" viewBox="-73.623 -78.055 147.245 156.11">
<path
d="M0.069,32.482L64.48-32.205H36.915v-45.85h-73.83l-0.139,45.85h-27.15L0.069,32.482z M73.623,78.055V59.632 H-73.623v18.423H73.623z"
transform="matrix(1 0 0 -1 0 0)"></path>
</symbol>
</svg></div>
<h3>SVG Sprite使用示意</h3>
<ul>
<li><svg class="webicon">
<use xlink:href="#qianbi"></use>
</svg>编辑信息</li>
<li><svg class="webicon">
<use xlink:href="#liwu"></use>
</svg>兑换礼物</li>
<li><svg class="webicon">
<use xlink:href="#shangchuan"></use>
</svg>上传文件</li>
</ul>
</div>
</body>
</html>
vue3+vite自定义svg图标组件
1、安装 vite–plugin–svg-icons
npm i fast-glob@3.2.11 -D
npm i vite-plugin-svg-icons@2.0.1 -D
2、创建图标文件夹
在src/assets文件夹下新建icons文件夹,用于存放下载的 SVG 图标
3、vite.config.js 插件配置
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
createSvgIconsPlugin({
// 指定需要缓存的图标文件夹
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
// 指定symbolId格式
symbolId: 'icon-[dir]-[name]',
})
],
resolve: {
alias: {
'@': path.resolve(__dirname, './src')
}
}
})
4、SvgIcon组件封装
<!--src/components/SvgIcon/index.vue-->
<template>
<svg
aria-hidden="true"
class="svg-icon"
:style="'width:' + size + ';height:' + size"
>
<use :xlink:href="symbolId" :fill="color"/>
</svg>
</template>
<script setup lang="ts">
import {computed} from 'vue';
const props = defineProps({
prefix: {
type: String,
default: 'icon'
},
iconClass: {
type: String,
required: false
},
color: {
type: String
},
size: {
type: String,
default: '1em'
}
});
const symbolId = computed(() => `#${props.prefix}-${props.iconClass}`);
</script>
<style scoped>
.svg-icon {
overflow: hidden;
fill: currentColor;
}
</style>
5、main.js 引入注册脚本
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from '@/router'
import store from '@/store'
// 不知道这个东西是哪来的,但是没它的话,html下面就没有那个Symbol的定义了
import 'virtual:svg-icons-register';
import SvgIcon from '@/components/SvgIcon/index.vue'
const app = createApp(App)
app.use(router)
app.use(store)
// 注册全局组件
app.component('SvgIcon',SvgIcon)
app.mount('#app')
6、Home.vue中使用SvgIcon组件
<template>
home
<svg-icon icon-class="tree" size="40px"/>
<svg-icon icon-class="tree2" size="50px"/>
</template>
<script setup>
</script>
<style lang="scss">
</style>
7、图标选择器
IconSelect.vue
在src/components文件夹下新建IconSelect文件夹,并在IconSelect文件夹下新建index.vue
<template>
<div class="icon-select">
<el-input
v-model="iconName"
clearable
placeholder="请输入图标名称"
@clear="filterIcons"
@input="filterIcons"
>
<template #suffix><i class="el-icon-search el-input__icon" /></template>
</el-input>
<div class="icon-select__list">
<div
v-for="(item, index) in iconList"
:key="index"
@click="selectedIcon(item)"
>
<svg-icon
color="#999"
:icon-class="item"
style="height: 30px; width: 16px; margin-right: 5px"
/>
<span>{{ item }}</span>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import SvgIcon from '@/components/SvgIcon/index.vue';
const icons = [] ;
const modules = import.meta.glob('../../assets/icons/*.svg');
for (const path in modules) {
const p = path.split('assets/icons/')[1].split('.svg')[0];
icons.push(p);
}
const iconList = ref(icons);
const iconName = ref('');
const emit = defineEmits(['selected']);
function filterIcons() {
iconList.value = icons;
if (iconName.value) {
iconList.value = icons.filter(item => item.indexOf(iconName.value) !== -1);
}
}
function selectedIcon(name) {
emit('selected', name);
document.body.click();
}
function reset() {
iconName.value = '';
iconList.value = icons;
}
defineExpose({
reset
});
</script>
<style lang="scss" scoped>
.icon-select {
width: 100%;
padding: 10px;
&__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>
Home.vue中使用IconSelect
<template>
home
<!-- <svg-icon icon-class="tree" size="40px"/>
<svg-icon icon-class="tree2" size="50px"/> -->
<div style="width:300px">
<icon-select @selected="selected"></icon-select>
</div>
</template>
<script setup>
import IconSelect from '@/components/IconSelect/index.vue'
import { reactive, ref } from "vue";
const state = reactive({
icon: '',
})
function selected(name) {
console.log(state.icon)
state.icon = name;
}
</script>
<style lang="scss"></style>
vue2自定义svg图标组件
1. 安装svg-sprite–loader
npm install svg-sprite-loader -D
2. 创建图标所在文件夹
在项目 src 目录下新建 src/icons/svg 目录(存放 svg 图标文件)。
3. 配置vue.config.js
const { defineConfig } = require('@vue/cli-service')
const path = require('path')
const resolve = dir => path.join(__dirname, dir)
module.exports = defineConfig({
transpileDependencies: true,
chainWebpack(config) {
// 配置 svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/icons'))
.end()
config.module
.rule('icons')
.test(/.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
}
})
4. SvgIcon.vue图标组件封装
在src/components下创建SvgIcon.vue
(或者:在src/components下创建SvgIcon文件夹,在里边创建index.vue)
<template>
<svg className="svg-icon" aria-hidden="true">
<use :xlink:href="iconName"/>
</svg>
</template>
<style>
.svg-icon {
width: 1.5em;
height: 1.5em;
}
</style>
<script>
export default {
props: {
iconClass: {
type: String,
required: true
}
},
computed: {
iconName () {
return `#icon-${this.iconClass}`
}
}
}
</script>
5.创建svg文件的入口文件icon.js
在 src/icons 下创建 icons 目录的入口文件 index.js ,负责svg文件的加载
import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'
Vue.component('svg-icon', SvgIcon)
/**
* require.context 的参数说明
* './svg' 代表要查找的文件路径
* false 代表是否查找子目录
* /.svg$/ 代表要匹配文件的正则
*
*/
const svg = require.context('./svg', false, /.svg$/)
const requireAll = (requireContext) => requireContext.keys().map(requireContext)
requireAll(svg)
6.main.js中引入icon.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import '@/icons'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
7. Home.vue中使用SvgIcon组件
<template>
<div>
Home
<svg-icon icon-class="tree"></svg-icon>
<svg-icon icon-class="tree2"></svg-icon>
</div>
</template>
<script>
export default {
name: 'Home',
components: {
}
}
</script>
<style>
</style>
原文地址:https://blog.csdn.net/qq_16992475/article/details/129695582
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_48866.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。