编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

小白从0搭建 Vite5 + Vue3 轮子:7. 全局使用SVG图标并批量导入

wxchong 2024-10-25 17:55:32 开源技术 11 ℃ 0 评论

vite-plugin-svg-icons是一个Vite插件,作用是将SVG图标文件转换为Vue组件,方便在Vue项目中使用。fast-glob 是一个用于快速遍历文件系统并匹配模式的库。

安装插件 vite-plugin-svg-icons 和 fast-glob 库

npm i vite-plugin-svg-icons fast-glob -D

在 /vite.config.js 中配置 plugins 项

.svg 图标的存放路径为 /src/assets/svg 文件夹中;将/src/assets/vue.svg 文件移到到 ./svg目录中。

// ...
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' 
export default defineConfig({
    plugins: [
        vue(),
        // svg
        createSvgIconsPlugin({
            // 指定需要缓存的图标文件夹
            iconDirs: [resolve(process.cwd(), 'src/assets/svg')],
            // 指定symbolID格式
            symbolId: 'svg-[dir]-[name]',
        }),
    ],
  	// ...
})

创建一个全局的Svg组件

/src/components/global/Svg.vue

<script setup>
import { defineProps, computed } from 'vue'
const props = defineProps({
    // 图标
    i: {
        style: String,
        default: 'logo',
        required: true,
    },
    // class 列表
    className: {
        type: String,
        default: '',
    },
    // 图标颜色
    color: {
        type: String,
        default: '#333333',
    },
    // 大小,单位px
    size: {
        type: String,
        default: '12px',
    },
})
// 对应 /vite.config.js 中 createSvgIconsPlugin.symbolId
const symbolId = computed(() => `#svg-${props.i}`)
const arrClass = computed(() => `i-svg ${props.className}`)
const strStyle = computed(
    () =>
        `color: ${props.color}; font-size: ${props.size}; width: ${props.size}; height: ${props.size};`,
)
</script>

<template>
    <svg aria-hidden="true" :class="arrClass" :style="strStyle">
        <use :xlink:href="symbolId" rel="external nofollow"></use>
    </svg>
</template>

<style scoped>
.i-svg {
    /**currentColor:准确讲应该是“当前的文字颜色” **/
    fill: currentColor;
    display: inline-flex;
    flex-flow: row, nowrap;
    justify-content: center;
    align-items: center;
}
</style>

创建 /src/compoents/install_global.js 文件,使/src/components/global/目录下的组件批量导入为全局组件。

/src/components/install_global.js

const mods = import.meta.glob('./global/*.vue')
export default function install(app) {
    for (const path in mods) {
        mods[path]().then(mod => {
            const file = mod.default
            // 注意,组件文件使用<script setup>是没有文件名的
            app.component(setName(file.__file), file)
        })
    }
}
// 设置文件名
function setName(str) {
    let arr = str.split('/')
    return arr[arr.length - 1].split('.')[0]
}

在 /src/main.js 中配置批量导入组件

添加
import install from './components/install_global.js'
import 'virtual:svg-icons-register'
install(app)

/src/main.js

// ...
import install from './components/install_global.js'
import 'virtual:svg-icons-register'

const app = createApp(App)
app.config.globalProperties.$http = req // axios
app.use(store) // vuex
install(app) // 批量引入全局组件
app.use(router) // 引用路由
app.mount('#app')

添加测试页 及 在组件中使用

/src/view/test/svg.vue

<template>
    <h4>SVG图标组件</h4>
    <p></p>
		<!-- 在组件中使用 -->
    <Svg i="vue" color="#283593" size="200px"></Svg>
</template>

<Svg i="vue" color="#283593" size="20px"></Svg>

i="vue" 对应 /src/assets/svg/vue.svg,刚才在 vite.config.js 和 /src/components/global/Svg.vue 中指定了对应关系。

icon1.svg 对应 i-icon1
dir/icon1.svg 对应 i-dir-icon1
dir/subdir/icon.svg 对应 i-dir-subdir-icon

添加路由
/src/router/test.js

// ...
const pSvg = () => import('@v/test/svg.vue')
const testRoutes = [
    {
        path: '/svg',
        name: 'svg',
        meta: {
            title: 'svg',
        },
        component: pSvg,
    },
  	// ...
 ]

添加访问按钮
/src/App.vue

<template>
    <main>
        <nav class="nav">
            <router-link to="/svg" active-class="on">SVG全局图标</router-link>
// ...

启动项目查看 npm run dev

----- End -----

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表