【项目实践】vue + vite 图标导入总结

vue + vite 图标导入总结

SVG 的使用

在页面中我们会使用到各种图标,为了保证图标在放大缩小不失真,通常会采用 SVG 来作为图标。

SVG(Scalable Vector Graphics)是一种基于XML的矢量图像格式,它可以用来创建清晰的、可缩放的图形,无论放大多少倍都不会失真。在Web开发中,SVG常用于制作图标,因为它具有以下优点:

  • 清晰度:SVG图标在任何分辨率下都能保持清晰。
  • 可编辑性:SVG是文本格式,可以使用文本编辑器进行修改。
  • 尺寸小:SVG图标文件通常比位图(如PNG或JPEG)更小,尤其在需要多个尺寸时。
  • 动画支持:SVG支持动画,可以通过CSS或JavaScript实现动态效果。
  • 可编程性:可以使用CSS或JavaScript直接操作SVG元素。

以下是SVG图标在HTML中直接使用的简单代码示例:

 html<!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <style>
         /* 你可以通过CSS来控制SVG图标 */
         .my-icon {
             width: 24px;
             height: 24px;
             fill: currentColor; /* 这会让SVG填充颜色跟随父元素的颜色 */
         }
     </style>
 </head>
 <body>
     <!-- 直接内联SVG图标 -->
     <svg class="my-icon" viewBox="0 0 24 24" id="icon-example">
         <path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7l3.59 3.59L17 7.41 15.59 9 12 12.59z"></path>
     </svg>
 ​
     <!-- 或者通过<use>标签引用外部SVG文件中的图标 -->
     <svg class="my-icon">
         <use xlink:href="#icon-example"></use> <!-- icons.svg是SVG文件,icon-example是图标在文件中的ID -->
     </svg>
 </body>
 </html>

在这个例子中,我们创建了两个SVG图标。第一个是内联SVG,直接在HTML中定义了图标路径。第二个是通过 <use> 标签引用了一个外部SVG文件中的图标。viewBox 属性定义了SVG的视口,d 属性包含了描述图形路径的数据。

注意,如果你使用 <use> 标签,你需要确保外部SVG文件已经被正确引入到你的HTML文档中,通常是通过<script><link> 标签。

阿里的 iconfont 的 symbol 引用就是通过 script 标签引入的,其原理是将所有图标的 svg 标签及内部 path 标签定义为字符串放在 iconfont.js 文件中,当 js 文件引入到页面后会将图标的字符串通过 innerHTML 转化为 DOM 标签作为 body 的第一个子元素插入到页面,代码如下:

 
 i = function() {
     var t, e = document.createElement("div");
     e.innerHTML = n._iconfont_svg_string_4570457,
     (e = e.getElementsByTagName("svg")[0]) && (e.setAttribute("aria-hidden", "true"),
     e.style.position = "absolute",
     e.style.width = 0,
     e.style.height = 0,
     e.style.overflow = "hidden",
     e = e,
     (t = document.body).firstChild ? s(e, t.firstChild) : t.appendChild(e))
 }
 ,
 document.addEventListener ? ~["complete", "loaded", "interactive"].indexOf(document.readyState) ? setTimeout(i, 0) : (o = function() {
     document.removeEventListener("DOMContentLoaded", o, !1),
     i()
 }

 

5-1.png

通过插件导入 icon 图标

vite-plugin-svg-icons 方式

针对每个图标都是一个 svg 文件这种情况,如果要单个引入就比较麻烦。假设图标都放在 src/assets/svg 目录下

5-3.png

我们可以使用 vite-plugin-svg-icons 插件来完成,其功能如下:

  • 预加载所有图标,项目运行时生成所有图标,只需操作DOM一次
  • 内置高速缓存功能,只有在文件被修改时才会重新生成
 # 安装
 yarn add vite-plugin-svg-icons -D
 # or
 npm i vite-plugin-svg-icons -D
 # or
 pnpm install vite-plugin-svg-icons -D

安装完成后需要在 vite.config.ts 进行如下配置:

 import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
 import path from 'path'
 ​
 export default () => {
   return {
     plugins: [
       createSvgIconsPlugin({
         // 指定要导入的图标所在的文件夹。
         iconDirs: [path.resolve(process.cwd(), 'src/icons')],
         // 指定symbol id的格式
         symbolId: 'icon-[dir]-[name]',
 ​
         /**
          * 定义图标插入的位置
          * @default: body-last
          */
         inject?: 'body-last' | 'body-first'
 ​
         /**
          * 定义 svg 标签的 id 值
          * @default: __svg__icons__dom__
          */
         customDomId: '__svg__icons__dom__',
       }),
     ],
   }
 }

在 src/main.ts 文件中引入注册脚本

 import 'virtual:svg-icons-register'

下是插入到页面的 svg 标签及图标,可以看出所有的图标都有加载

5-2.png

对于 svg 图标一般是修改其颜色和大小,通常会套一个 i 标签来定义,同时会传入一个图标名称,这三者作为组件的属性,这样就可以定义一个 ICON 组件了

 <!-- src/components/icon.vue -->
 <style>
 .icon {
     height: 1em;
     width: 1em;
     line-height: 1em;
     display: inline-flex;
     justify-content: center;
     align-items: center;
     position: relative;
     fill: currentColor;
     font-size: inherit;
 }
 </style>
 <template>
     <i class="icon" :style="{ color: color, fontSize: size + 'px' }">
         <svg aria-hidden="true">
             <use :xlink:href="symbolId"></use>
         </svg>
     </i>
 </template>
 <script setup lang="ts">
 import { computed, unref } from 'vue';
 ​
 const props = defineProps({
     prefix: {
       type: String,
       default: 'icon',
     },
     // icon name
     iconName: {
         type: String,
         required: true,
     },
     // icon color
     color: {
         type: String,
         default: '#000'
     },
     // icon size
     size: {
         type: Number,
         default: 16
     }
 })
 const symbolId = computed(() => `#${props.prefix}-${props.iconName}`)
 </script>

使用

 <template>
     <icon iconName="add" />
     <icon iconName="delete" />
     <icon iconName="export" />
     <icon iconName="edit" />
 </template>
 <script setup lang="ts">
     import Icon from "@/components/Icon.vue";
 </script>

效果如下图:

5-4.png

该插件原理大致总结为:根据 iconDirs 提供的图标所在的文件夹自动查找所有的 SVG 文件,将这些 SVG 文件全部添加到 svg 标签下,每一个图标对应一个 symbol 标签,每个标签的 id 为配置项中 symbolId 。通过 use :xlink:href="symbolId" 引用图标。

unplugin-icons 方式

GitHub - unplugin/unplugin-icons 是一个用于优化图标管理与使用的开发插件,它允许开发者以一种高效且自动化的形式在项目中使用图标,无需手动创建或导入每一个图标组件。使用此插件不需要将图标先下载到本地,可以从一些开源的图标库中自动导入图标。其使用方式如下:

安装

 npm i -D unplugin-icons

安装图标库:使用 Iconify 作为图标库

 
 # 安装完整版本
 npm i -D @iconify/json
 # 按图标集安装,例如,要安装 Material Design Icons
 npm i -D @iconify-json/mdi

在 vite.config.ts 进行如下配置:

 // vite.config.ts
 import Icons from 'unplugin-icons/vite'
 ​
 export default defineConfig({
   plugins: [
     Icons({ /* options */ }),
   ],
 })

使用

 <script setup>
 import IconAccessPointCheck from '~icons/mdi/access-point-check';
 import IconAccountBox from '~icons/mdi/account-box'
 </script>
 ​
 <template>
   <icon-access-point-check/>
   <icon-account-box style="font-size: 2em; color: red"/>
 </template>

 

效果如下图:

5-5.png

为了提高工作效率,通过在配置项中启用“ autoInstall ”选项,可以让 unplugin-icons 来负责安装工作,此时就不需要安装图标库了

 // vite.config.ts
 import Icons from 'unplugin-icons/vite'
 ​
 export default defineConfig({
   plugins: [
     Icons({ 
       // experimental
       autoInstall: true,
     }),
   ],
 })

 

5-6.png

unplugin-icons 的图标解析与转换过程总结如下:

  1. 图标名称识别
  • 在Vue模板或JSX中,开发者使用图标名称(如 <i-mdi-home></i-mdi-home>),unplugin-icons 会通过代码分析识别这些图标名称。
  1. 图标解析
  • 图标名称映射:根据配置的图标集,unplugin-icons 查找图标名称与实际图标资源之间的映射关系。这通常涉及到读取图标集的元数据,如JSON文件,里面记录了每个图标的名称和对应的SVG路径。
  • 图标资源提取:一旦找到图标名称对应的资源位置,插件会读取SVG文件或从图标库API获取SVG数据。
  1. 图标转换
  • SVG到Vue组件:获取到SVG数据后,unplugin-icons 将SVG内容转换为Vue组件代码。这个过程可能包括:

    • 图标优化:对SVG进行优化,比如去除不必要的属性、标准化样式等,确保图标在不同浏览器和平台上的表现一致。
    • 组件模板构造:构造Vue组件模板,将SVG内容包裹在Vue的<template>标签中,并添加必要的属性和事件绑定。
    • 动态导入处理:如果配置了按需加载,插件会生成动态导入代码,确保图标只在真正使用时加载。
  • 组件注册:生成的Vue组件需要在项目中注册,以便在模板中直接使用。unplugin-icons 通常会自动处理组件的注册,可能通过全局注册或按需注册的方式。

  1. 自动导入
  • 依赖注入:通过与unplugin-auto-import的集成,unplugin-icons 在编译时自动插入必要的导入语句,使得开发者无需手动导入图标组件。
  1. 最终输出
  • 编译产物:经过上述步骤,原本的图标名称在编译后的代码中被替换为实际的Vue组件调用,同时图标组件按需加载和自动导入的逻辑也被正确插入。最终,构建工具输出的代码中包含了最小化且优化过的图标组件,既减少了包体积,又简化了开发流程。

整个过程确保了图标资源的高效利用,同时保持了代码的清晰和易维护性。

文章转自:https://juejin.cn/post/7377191678862475301

Vue + Vite 项目中配置 PWA 选项来启用离线缓存,你可以按照以下步骤进行操作: 1. 首先,安装 `vite-plugin-pwa` 插件。可以使用以下命令进行安装: ```bash npm install vite-plugin-pwa --save-dev ``` 2. 在 `vite.config.js` 中导入 `vite-plugin-pwa` 插件,并将其添加到插件列表中: ```javascript import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; import VitePWA from 'vite-plugin-pwa'; export default defineConfig({ plugins: [ vue(), VitePWA({ // 配置选项 }) ] }); ``` 3. 在配置选项中,可以设置 `manifest` 和 `workbox` 两个子选项来配置 PWA 功能。在 `manifest` 中,你可以设置应用的名称、图标、主题色等信息。在 `workbox` 中,则可以配置缓存策略、路由规则等离线缓存相关的信息。 ```javascript VitePWA({ manifest: { name: 'My App', short_name: 'My App', icons: [ { src: '/icons/android-chrome-192x192.png', sizes: '192x192', type: 'image/png' }, { src: '/icons/android-chrome-512x512.png', sizes: '512x512', type: 'image/png' } ], theme_color: '#ffffff', background_color: '#ffffff' }, workbox: { // 配置离线缓存策略 } }) ``` 4. 最后,在 `index.html` 文件中添加 PWA 相关的 meta 标签,以便浏览器可以识别应用为 PWA 应用,并将其添加到主屏幕。 ```html <link rel="manifest" href="/manifest.json"> <meta name="theme-color" content="#ffffff"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> ``` 以上就是在 Vue + Vite 项目中配置 PWA 选项来启用离线缓存的步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值