vue-展示-选择-svg-icon

320 阅读1分钟
  1. 下载icon-font阿里图标 image.png
  2. 引入iconfont.js文件到静态资源文件

image.png

  1. 在main.ts中引入
import "@/assets/iconfont/iconfont.js"
  1. 创建一个SvgIcon组件
<template>
	<svg aria-hidden="true" :class="`iconfont ${className}`" 
            :style="`width:${width};height:${height};color:${color};${myStyle};`" 
            :fill="color">
		<use :xlink:href="symbolId" />
	</svg>
</template>
<script lang="ts" setup>
import { computed } from 'vue';
interface IProps {
	prefix?: string;
	name: string;
	color?: string;
	width?: string;
	height?: string;
	className?: string;
	myStyle?: string;
}
const props = withDefaults(defineProps<IProps>(), {
	prefix: 'icon',
	color: '#202020',
	width: '14px',
	height: '14px',
	className: '',
	myStyle: '',
});
const symbolId = computed(() => `#${props.prefix}-${props.name.replace('icon-', '')}`);
</script>
  1. 在main.ts中注册全局组件
// 引入组件
import svgIcon from "@/components/iconA/index.vue";
// 注册为全局组件
app.component('svgIcon',svgIcon)
  1. 所有组件中都可以使用
<svg-icon name="icon-PDF"  width="12px" height="12px"></svg-icon>

选择所有svg

image.png

1.子组件内容

<template>
	<el-popover v-model:visible="iconListVisible" ref="iconListPopover" placement="top-start" trigger="click" popper-class="mod-sys__menu-icon-popover">
		<template #reference> <el-input v-model="state.icon" :readonly="true" placeholder="请选择Icon"></el-input></template>
		<template #default>
			<div class="mod-sys__menu-icon-inner">
				<div class="mod-sys__menu-icon-list">
					<el-button
						v-for="(item, index) in state.iconList"
						:key="index"
						@click.stop="iconListCurrentChangeHandle(item, index)"
						:class="{ 'is-active': state.icon === item }"
						@mouseenter="state.enterItem = item"
						@mouseleave="state.enterItem = ''"
					>
						<svg
							class="icon-svg"
							aria-hidden="true"
							style="width: 18px; height: 18px"
							:fill="state.icon === item || state.enterItem === item ? state.iconColor : ''"
						>
							<use :xlink:href="`#${item}`"></use>
						</svg>
					</el-button>
				</div>
			</div>
		</template>
	</el-popover>
</template>

<script setup lang="ts">
import { reactive, ref, defineEmits, watch, onMounted } from 'vue';
const props = defineProps({
	initIcon: String,
});
const emits = defineEmits(['update:initIcon']);
const iconListVisible = ref(false);
const state = reactive({
	icon: '',
	iconList: [] as string[],
	enterItem: '',
	iconColor: '#2879ff', 
});

const iconListCurrentChangeHandle = (icon: string) => {
	state.icon = icon;
	iconListVisible.value = false;
	emits('update:initIcon', icon);
};
// 获取svg图标(id)列表
const getIconList = (): string[] => {
	const rs: string[] = [];
	const list = document.querySelectorAll('svg symbol');
	for (let i = 0; i < list.length; i++) {
		rs.push(list[i].id);
	}
	console.log(rs);
	return rs;
};
onMounted(() => {
	state.iconList = getIconList();
});
watch(
	() => props.initIcon,
	(val: any) => {
		console.log(val);
		state.icon = val;
	},
	{
		immediate: true,
	}
);
</script>

<style lang="scss">
.mod-sys__menu-icon-popover {
	width: 340px !important;
	// overflow-y: hidden !important;
}
.mod-sys__menu-icon-inner {
	width: 320px;
	max-height: 300px;
	// overflow-x: hidden;
	overflow-y: auto !important;
}
.mod-sys__menu-icon-list {
	width: 320px !important;
	padding: 0;
	margin: -8px 0 0 -8px;
}
.mod-sys__menu-icon-list > .el-button {
	padding: 8px;
	margin: 8px 0 0 8px;
}
</style>

2.使用

<el-form-item prop="icon" label="Icon" class="icon-list">
    <UniSelectIcon v-model:initIcon="state.formData.icon" />
</el-form-item>