封装图标组件,优化项目

110 阅读1分钟

首先要把 icons 文件夹中的图标打包成 svg 雪碧图(精灵图),参考文档

然后我们就可以在控制台看到

接下来我们要安装一个插件

pnpm install vite-plugin-svg-icons -D

配置插件

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite'
import { VantResolver } from 'unplugin-vue-components/resolvers'
// 第一步
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
//第二步
import path from 'path'
// https://vitejs.dev/config/
export default defineConfig({
    plugins: [
        vue(),
        Components({
            dts: false,
            resolvers: [VantResolver({ importStyle: false })]
        }),
        // 第三步
        createSvgIconsPlugin({
            iconDirs: [path.resolve(process.cwd(), 'src/icons')]
        })
    ],
    resolve: {
        alias: {
            '@': fileURLToPath(new URL('./src', import.meta.url))
        }
    }
})

导入到main.ts

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import pinia from './stores'
// mark
import 'virtual:svg-icons-register'
import 'vant/lib/index.css'
import './styles/main.scss'

const app = createApp(App)

app.use(pinia)
app.use(router)

app.mount('#app')

最后让我们来测试使用一下svg 精灵地图

这个svg标签是html自带的一种标签,格式就是固定格式,代码如下:

<svg aria-hidden="true">
    <!-- #icon-文件夹名称-图片名称 -->
    <use href="#icon-login-eye-off" />
</svg>

没问题后我们就可以封装成组件来使用了,基建工作。
代码如下:

<script setup lang="ts">
    // 提供 name 属性即可
    defineProps < {
        name: string
    } > ()
</script>

<template>
    <svg aria-hidden="true" class="cp-icon">
        <use :href="`#icon-${name}`" />
    </svg>
</template>

<style lang="scss" scoped>
    .cp-icon {
        // 和 font-size 一样大
        width: 1em;
        height: 1em;
    }
</style>

注意:有些图标可以根据 style 中 color 的值来设置颜色,图标是否有这个功能取决于 UI 做图片时否开启。
如果是用vue3+ts写的项目,还需要定义一下类型,如果没有用到ts的话,这里可以忽略掉这段代码

import CpNavBar from '@/components/CpNavBar.vue'
import CpIcon from '@/components/CpIcon.vue'

declare module 'vue' {
    interface GlobalComponents {
        CpNavBar: typeof CpNavBar
        CpIcon: typeof CpIcon
    }
}

然后我们就可以正常使用了

<cp-icon  name="login-eye-on"></cp-icon>