欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue3引入SVG圖標的流程步驟

 更新時間:2024年09月27日 11:27:44   作者:知否技術(shù)  
我們在開發(fā) Vue 項目的時候會使用一些前端組件庫,例如 Element、Ant Design 等,這些組件庫雖然方便,但是也有一些缺點,比如內(nèi)置的圖標太少,例如我們開發(fā)醫(yī)療、財務(wù)、工程等一些前端項目,內(nèi)置的圖標不能滿足我們的需求,所以我們常常在Vue項目中引入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 cli實現(xiàn)項目登陸頁面流程詳解

    vue cli實現(xiàn)項目登陸頁面流程詳解

    CLI是一個全局安裝的npm包,提供了終端里的vue命令。它可以通過vue create快速搭建一個新項目,或者直接通過vue serve構(gòu)建新想法的原型。你也可以通過vue ui通過一套圖形化界面管理你的所有項目
    2022-10-10
  • vue內(nèi)置組件keep-alive事件動態(tài)緩存實例

    vue內(nèi)置組件keep-alive事件動態(tài)緩存實例

    這篇文章主要介紹了vue內(nèi)置組件keep-alive事件動態(tài)緩存實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • Vue-cli打包后部署到子目錄下的路徑問題說明

    Vue-cli打包后部署到子目錄下的路徑問題說明

    這篇文章主要介紹了Vue-cli打包后部署到子目錄下的路徑問題說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Vue使用Vue-cropper實現(xiàn)圖片裁剪

    Vue使用Vue-cropper實現(xiàn)圖片裁剪

    這篇文章主要為大家詳細介紹了Vue使用Vue-cropper實現(xiàn)圖片裁剪,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • 一文帶你搞懂Vue3?defineModel中的雙向綁定

    一文帶你搞懂Vue3?defineModel中的雙向綁定

    隨著vue3.4版本的發(fā)布,defineModel也正式轉(zhuǎn)正了,它可以簡化父子組件之間的雙向綁定,是目前官方推薦的雙向綁定實現(xiàn)方式,下面就跟隨小編一起深入了解一下defineModel的使用吧
    2024-02-02
  • Vue項目中input框focus時不調(diào)出鍵盤問題的解決

    Vue項目中input框focus時不調(diào)出鍵盤問題的解決

    這篇文章主要介紹了Vue項目中input框focus時不調(diào)出鍵盤問題的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • 基于element-ui的rules中正則表達式

    基于element-ui的rules中正則表達式

    今天小編就為大家分享一篇基于element-ui的rules中正則表達式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • Vue開發(fā)中整合axios的文件整理

    Vue開發(fā)中整合axios的文件整理

    這篇文章主要給大家整理了在Vue開發(fā)中整合axios要用到的文件,在vue開發(fā)中,不可避免要整合axios,文中通過示例代碼介紹的非常詳細,需要的朋友們下面來一起看看吧。
    2017-04-04
  • 學習Vue框架中必掌握的重點知識

    學習Vue框架中必掌握的重點知識

    這篇文章主要介紹了學習Vue中必掌握的重點知識,想了解vue的同學可以參考下
    2021-04-04
  • VUEX-action可以修改state嗎

    VUEX-action可以修改state嗎

    這篇文章主要介紹了VUEX-action可以修改state嗎,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-11-11

最新評論