听劝,前端的icon图片告别.png用.svg吧

7,987 阅读2分钟

简介: svg vite-svg-loader svg动态调整颜色 底部导航栏

为什么是SVG而不是PNG

在web开发中我们经常会有图片icon的处理需求,但是因为不同屏幕尺寸不一样,所以我们前端一般使用图片时都会使用2倍或者3倍尺寸png图,以便在更大尺寸的屏幕上,拥有更好的视觉体验,不会出现放大后的图片失真。

PNG 图像适用于复杂的照片和图像,但对于包含大量线条和文本的图形,可能不太适合,因为它们在缩放时可能会失去清晰度。SVG 图像非常适合包含线条、文本和复杂形状的图形,因为它们可以无损缩放,而不会失去质量。 这使得SVG成为Webp图片展示更好的解决方案。

以下示意为 vue3+vite环境,其他按照对应情况调整,大同小异。

怎么用

  • 引入个插件 npm i vite-svg-loader --save-dev

插件具体使用文档:传送门

进阶之动态修改颜色

如果你无需动态修改你的图片颜色,你直接?url导入即可。

如果你想动态修改颜色,就像底部导航栏FooterNavBar 需要根据active的true?false调整颜色,那么你可以使用?component来导入

使用步骤

    1. 作为component引入svg
    1. 使用<component :is="xx" /> 在插槽动态展示组件
    1. 使用 css 结合 v-bind()来动态设置svg的fill属性

你可能会遇到一些问题

    1. svg尺寸不对
    • 编辑器打开你的svg文件,删除svg上的 width 和 height 即可
    • image.png
    1. svg修改了颜色无效
    • 编辑器打开你的svg文件,将 fill改为 fill='' 或者直接删除fill
    • 检查你的css 是否修改了path的 fill

你可参考这个示意,一个使用vant的tabBar自定义Icon的实现,它使用svg来作为icon

<template>
  <van-tabbar v-model="activeNav" class="footerbar-comp-container">
    <van-tabbar-item v-for="navItem in navItems" :key="navItem.name" :name="navItem.name" :activeColor="activeColor" :inactiveColor="inactiveColor">
      <span>{{ navItem.text }}</span>
      <template #icon>
         <!-- 这里使用componen动态加载icon组件 -->
        <component :is="navItem.icon"></component>
      </template>
    </van-tabbar-item>
  </van-tabbar>
</template>
<script setup lang="ts">
import { reactive, toRefs } from "vue";
// 下方使用了?component 导入了两个svg
import homeIcon from "@/assets/icons/home.svg?component"; 
import meIcon from "@/assets/icons/me.svg?component";


// 这里定义了(非)激活状态下的颜色,这里没必要用ref响应式
const activeColor = "#1989fa";
const inactiveColor = "#7d7e80";

const option = reactive({
  activeNav: "home",
  navItems: [
    {
      text: "首页",
      name: "home",
      icon: homeIcon,
      path: "/home",
    },
    {
      text: "我的",
      name: "me",
      icon: meIcon,
      path: "/me",
    },
  ],
});

const { activeNav, navItems } = toRefs(option);
</script>
<style lang="less" scoped>
.footerbar-comp-container {
    // 使用deep css修改svg和path的fill:css属性以达到动态修改颜色的目的。 
  :deep(.van-tabbar-item__icon) {
    width: 24px;
    height: auto;
     svg,path  {
      fill: v-bind(inactiveColor); 
    }
  }
  :deep(.van-tabbar-item--active) {
     svg,path  {
      fill: v-bind(activeColor);
    }
  }
}
</style>