Vue3引入SVG圖標的流程步驟
1. 前言
我們在開發(fā) Vue 項目的時候會使用一些前端組件庫,例如 Element、Ant Design 等。
這些組件庫雖然方便,但是也有一些缺點,比如內(nèi)置的圖標太少。
例如我們開發(fā)醫(yī)療、財務(wù)、工程等一些前端項目,內(nèi)置的圖標不能滿足我們的需求。所以我們需要引入外部的圖標。
我們常常在 Vue 項目中引入 SVG 圖標。
2. 效果展示
3. SVG 簡介
SVG 指可伸縮矢量圖形 (Scalable Vector Graphics)。
SVG 是使用 XML 來描述二維圖形和繪圖程序的語言。
說白了 SVG 就跟 jpg、png 一樣,都是圖形。只不過這玩意是用 xml 語言設(shè)計開發(fā)的矢量圖。
因為是矢量圖,所以不管放大還是縮小,都不會失真。
我們分別看3個相同名稱不同尺寸的 SVG 圖標:
我們用 vscode 打開一個 SVG 圖標,發(fā)現(xiàn)它由很多標簽組成:
如果想深入了解 SVG ,大家可以去以下網(wǎng)站學習
https://www.runoob.com/svg/svg-tutorial.html https://developer.mozilla.org/zh-CN/docs/Web/SVG
4. 下載 SVG 圖標
網(wǎng)上可以下載 SVG 圖標的網(wǎng)站有很多,這里我強烈推薦阿里巴巴的 iconfont ,因為它有海量免費的圖標供大家學習使用。
官網(wǎng):
https://www.iconfont.cn/
1.選擇圖標,點擊下載按鈕
2.選擇顏色和尺寸之后,點擊下載 SVG 格式
3.添加到購物車,批量下載
我們也可以將要下載的圖標添加到購物車,然后批量下載
下載之后,接下來我們需要 在 vue 項目中引入這些圖標。
5. Vue3 引入 SVG 圖標
前提:使用 Vite 腳手架開發(fā) Vue3 項目。
在 Vite 中使用 Vue3 引入 SVG 圖標,我們需要借助以下插件:
vite-plugin-svg-icons
vite-plugin-svg-icons 是一個 Vite 插件,它的主要功能是將 SVG 圖標轉(zhuǎn)換為 Vue 組件,并自動導入到項目中。
5.1 安裝插件
npm i vite-plugin-svg-icons -D
安裝之后運行程序如果報這個錯誤,需要再安裝 fast-glob 插件
npm i fast-glob -D
5.2 main.js 中注冊插件
import 'virtual:svg-icons-register'
5.3 配置 vite.config.js
import { defineConfig } from "vite"; import vue from "@vitejs/plugin-vue"; import { createSvgIconsPlugin } from "vite-plugin-svg-icons"; import { resolve } from "path"; const pathSrc = resolve(__dirname, "src"); export default defineConfig({ plugins: [ vue(), createSvgIconsPlugin({ // 指定需要緩存的圖標文件夾 iconDirs: [resolve(pathSrc, "assets/icons")], // 指定symbolId格式 symbolId: "icon-[dir]-[name]", }),], resolve: { // 設(shè)置別名 alias: { '@': resolve(__dirname, resolve(__dirname, "./src")) } }, });
其中最關(guān)鍵的是指定 svg 圖標的存放位置:
5.4 封裝展示 SVG 圖標的 icon 組件
1.:xlink:href 用來綁定圖標的名稱,名稱前要加前綴 icon
2.fill 屬性用來設(shè)置圖標的顏色
<template> <svg aria-hidden="true" :fill="color" :style="'width:' + size + ';height:' + size"> <use :xlink:href="symbolId" rel="external nofollow" /> </svg> </template> <script setup> import { computed } from "vue"; const props = defineProps({ // icon 名字 name: { type: String, default: "", }, // 填充顏色 color: { type: String, default: "black", }, // 大小 size: { type: String, default: "1em", }, }); const symbolId = computed(() => `#icon-${props.name}`); </script>
5.5 使用組件
<template> <div class="content"> <SvgIcon name="client" size="10rem" /> <SvgIcon name="client" size="10rem" color="red" /> <SvgIcon name="client" size="10rem" color="green" /> </div> </template> <script setup> import SvgIcon from "@/components/SvgIcon/index.vue"; </script> <style lang="scss" scoped></style>
6. 批量導入 SVG 圖標
1.import.meta.glob 用來動態(tài)導入所有 svg 圖標
2.獲取所有圖標的名稱
<template> <div class="content"> <SvgIcon v-for="(iconName, index) in allIconNames" :key="index" :name="iconName" size="5rem" /> </div> </template> <script setup> import SvgIcon from "@/components/SvgIcon/index.vue"; import { onMounted, toRef, ref } from "vue"; const allIconNames = ref([]); // 所有的圖標名稱集合 onMounted(() => { loadAllIcons(); }); // 獲取所有 icon const loadAllIcons = () => { const icons = import.meta.glob("@/assets/icons/*.svg"); for (const icon in icons) { // 獲取 icon 名稱 const iconName = icon.split("/src/assets/icons/")[1].split(".")[0]; allIconNames.value.push(iconName); } }; </script> <style lang="scss" scoped></style>
7. 開發(fā) SVG 搜索組件
這里我們使用 element-plus 作為前端組件庫。
我們主要用到 el-input、el-popover、el-scrollbar、el-tooltip 組件。
在 components 文件夾下新建 SelectIcon 組件
在開發(fā)這個組件之前,我們先想一下流程:
1.首先封裝 el-input,prepend 需要用 SvgIcon 展示選中圖標,v-model 需要綁定該圖標的名稱。
2.點擊 el-input, 彈出 el-popover,也就是需要給 el-popover 綁定 visible。
3.el-popover上面需要展示搜索框,下面需要展示所有的圖標。
// 加載 icon onMounted(() => { loadAllIcons(); }); // 獲取所有圖標 const loadAllIcons = () => { const icons = import.meta.glob("@/assets/icons/*.svg"); for (const icon in icons) { const iconName = icon.split("/src/assets/icons/")[1].split(".")[0]; allIconNames.value.push(iconName); } filterIconNames.value = allIconNames.value; };
4.圖標太多需要滾動,所以需要 el-scrollbar 組件進行包裹。
5.篩選圖標需要根據(jù)所有 SVG 的名稱是否包含 filterName
// 篩選 icon const filterIcon = () => { if (filterValue.value) { filterIconNames.value = allIconNames.value.filter((iconName) => iconName.includes(filterValue.value) ); } else { filterIconNames.value = allIconNames.value; } };
6.點擊圖標需要更新父組件綁定的值
update:modelValue 是 v-model 指令的默認事件,用于在組件內(nèi)部通知父組件更新綁定的值。
const handleSelect = (iconName) => { emit("update:modelValue", iconName); visible.value = false; };
<el-form-item label="圖標:" prop="icon" > <icon-select ref="IconSelectRef" v-model="sysMenu.icon" /> </el-form-item>
7.1 SelectIcon 組件完整代碼
<template> <div class="content"> <el-input style="width: 100%" v-model="inputIconValue" readonly placeholder="點擊選擇圖標" @click="visible = !visible" > <template #prepend> <SvgIcon :size="20" :name="inputIconValue" /> </template> </el-input> <el-popover shadow="none" :visible="visible" placement="bottom-end" trigger="click" width="400" > <template #reference> <div @click="visible = !visible"> <i-ep-caret-top v-show="visible" /> <i-ep-caret-bottom v-show="!visible" /> </div> </template> <!-- 下拉選擇彈窗 --> <div> <el-row :gutter="10"> <el-col :span="18"> <el-input v-model="filterValue" placeholder="輸入圖標名稱" clearable @input="filterIcon" /> </el-col> <el-col :span="6"> <el-button @click="closeIcon()">關(guān)閉</el-button> </el-col> </el-row> <el-divider border-style="dashed" /> <el-scrollbar height="300px"> <div class="icon-list"> <el-tooltip v-for="(iconName, index) in filterIconNames" :key="index" :content="iconName" placement="bottom" effect="light" > <div class="icon-item" @click="handleSelect(iconName)"> <SvgIcon :name="iconName" /> </div> </el-tooltip> </div> </el-scrollbar> </div> </el-popover> </div> </template> <script setup> import SvgIcon from "@/components/SvgIcon/index.vue"; import { onMounted, toRef, ref } from "vue"; const visible = ref(false); // 彈窗顯示狀態(tài) const allIconNames = ref([]); // 所有的圖標名稱集合 const filterIconNames = ref([]); // 篩選之后名稱集合 const filterValue = ref(""); // 篩選的值 // 修改父組件關(guān)聯(lián)的值 const emit = defineEmits(["update:modelValue"]); const props = defineProps({ modelValue: { type: String, require: false, default: "", }, }); const inputIconValue = toRef(props, "modelValue"); // 加載 icon onMounted(() => { loadAllIcons(); }); // 獲取所有圖標 const loadAllIcons = () => { const icons = import.meta.glob("@/assets/icons/*.svg"); for (const icon in icons) { const iconName = icon.split("/src/assets/icons/")[1].split(".")[0]; allIconNames.value.push(iconName); } filterIconNames.value = allIconNames.value; }; // 篩選 icon const filterIcon = () => { if (filterValue.value) { filterIconNames.value = allIconNames.value.filter((iconName) => iconName.includes(filterValue.value) ); } else { filterIconNames.value = allIconNames.value; } }; // 選擇 icon const handleSelect = (iconName) => { emit("update:modelValue", iconName); visible.value = false; }; // 關(guān)閉組件 const closeIcon = () => { visible.value = false; filterValue.value = ""; filterIconNames.value = allIconNames.value; }; </script> <style lang="scss" scoped> .el-divider--horizontal { margin: 10px auto !important; } .icon-list { display: flex; flex-wrap: wrap; .icon-item { display: flex; justify-content: center; padding: 5px 0px; margin: 5px; width: 10%; cursor: pointer; border: 1px solid #ccc; &:hover { color: var(--el-color-primary); border-color: var(--el-color-primary); transition: all 0.2s; transform: scaleX(1.1); } } } </style>
以上就是Vue3引入SVG圖標的流程步驟的詳細內(nèi)容,更多關(guān)于Vue3引入SVG圖標的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue內(nèi)置組件keep-alive事件動態(tài)緩存實例
這篇文章主要介紹了vue內(nèi)置組件keep-alive事件動態(tài)緩存實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10Vue項目中input框focus時不調(diào)出鍵盤問題的解決
這篇文章主要介紹了Vue項目中input框focus時不調(diào)出鍵盤問題的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-04-04