首页 > 其他分享 >【vue3】svg组件

【vue3】svg组件

时间:2024-09-29 09:45:15浏览次数:11  
标签:return name svg vue3 组件 import SvgIcon icon

一、Svg组件化支持插件

vite.config.ts

import { createSvgIconsPlugin } from "vite-plugin-svg-icons";//svgIcon
plugins:[
// svg组件化支持
    createSvgIconsPlugin({
      iconDirs: [pathResolve("../src/assets/svg")],
      // 指定symbolId格式
      symbolId: "icon-[name]",
      customDomId: "xxx-svgs", // 避免多项目互相影响
    }),
],

注:svg文件目录:/src/assets/svg/**

二、Svg组件

SvgIcon.vue

<template>
  <component
    :class="svgClass"
    :is="renderIcon(name)"
    :style="size ? { width: size, height: size } : ''"
  />
</template>

<script>
  import { defineComponent, computed } from 'vue';
  import { renderIcon } from './index';

  export default defineComponent({
    name: 'SvgIcon',
    props: {
      name: {
        type: String
      },
      className: {
        type: String,
        default: ''
      },
      size: {
        type: [Number, String],
        default: ''
      }
    },
    setup(props) {
      const svgClass = computed(() => {
        if (props.className) {
          return 'svg-icon ' + props.className;
        } else {
          return 'svg-icon';
        }
      });
      return { svgClass, renderIcon };
    }
  });
</script>

<style scoped>
  .svg-icon {
    display: inline-block;
    width: 1em;
    height: 1em;
    vertical-align: -0.15em;
    fill: currentColor;
    overflow: hidden;
  }

  .svg-external-icon {
    background-color: currentColor;
    mask-size: cover !important;
    display: inline-block;
  }
</style>

index.ts

import { App } from 'vue';
import { h } from 'vue';
import SvgIcon from './SvgIcon.vue';
import 'virtual:svg-icons-register';
import * as ElementPlusIconsVue from '@element-plus/icons-vue';
const svgModules = import.meta.glob('/src/assets/svg/*.svg');

// 图标名集合-element
const elementIconNames = Object.keys(ElementPlusIconsVue);
// 图标名集合-svg文件
const svgIconNames = Object.keys(svgModules).map((item) =>
  item.replace(/^\/src\/assets\/svg\/(.*).svg$/, '$1')
);

const svgIconPlugin = {
  install(app: App): void {
    // 全局挂载
    app.component('SvgIcon', SvgIcon);
  }
};

// 是ele+图标
export const isElementPlusIcon = (name) => {
  return name?.startsWith('el-') || elementIconNames.includes(name);
};

// 是本地svg图标
export const isSvgIcon = (name) => {
  return svgIconNames.includes(name);
};

function toPascalCase(name: string): string {
  // 分割字符串并处理每个部分
  return name
    .split('-')
    .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
    .join('');
}

/* 根据图标名获取图标 */
export const renderIcon = (name) => {
  if (!name) return;

  // element+
  if (isElementPlusIcon(name)) {
    const componentName = name.replace('el-', '');
    return ElementPlusIconsVue[toPascalCase(componentName)];
  }

  // svg-icon
  if (isSvgIcon(name)) {
    return h(
      'svg',
      {
        class: 'svg-icon'
      },
      {
        default: () => [
          h('use', {
            'xlink:href': '#icon-' + name
          })
        ]
      }
    );
  }

  return;
};

export default svgIconPlugin;

三、引入及应用

main.ts引入

import SvgIcon from '@/components/svgIcon'; // svg封装插件
// 全局注册矢量图标库
app.use(SvgIcon);

应用一、Element+ icon:本地svg图标

<el-input
  v-model="keyword"
  :prefix-icon="renderIcon('login-key')"
 />
<script setup lang="ts">
  import { renderIcon } from '@/components/SvgIcon';
</script>

应用二、Element+ icon:Element自带图标

<el-button :icon="renderIcon('el-search')">
  搜索
</el-button>
<script setup lang="ts">
  import { renderIcon } from '@/components/SvgIcon';
</script>

应用三、常规组件使用

<SvgIcon name="back_top" />

标签:return,name,svg,vue3,组件,import,SvgIcon,icon
From: https://www.cnblogs.com/yiping5/p/18438941

相关文章

  • VCL界面组件DevExpress VCL v24.1.6全新发布
    DevExpressVCLControls是Devexpress公司旗下老牌的用户界面套包,所包含的控件有:数据录入、图表、数据分析、导航、布局等。该控件能帮助您创建优异的用户体验,提供高影响力的业务解决方案,并利用您现有的VCL技能为未来构建下一代应用程序立即获取DevExpressVCLv24.1.6正式版具......
  • 第四章 Vue3视图渲染技术
    第四章Vue3视图渲染技术4.1模版语法Vue使用一种基于HTML的模板语法,使我们能够声明式地将其组件实例的数据绑定到呈现的DOM上。所有的Vue模板都是语法层面合法的HTML,可以被符合规范的浏览器和HTML解析器解析。在底层机制中,Vue会将模板编译成高度优化的JavaSc......
  • Vue3 + Pinia 仿抖音项目:移动端最佳实践,体验原生App般流畅
    嗨,大家好,我是小华同学,关注我们获得“最新、最全、最优质”开源项目和高效工作学习方法摘要:在移动端开发领域,Vue.js一直以其轻量级和易用性著称。今天,我们要介绍的是一个将Vue3和Pinia结合使用的开源项目——Douyin-Vue,这是一个模仿抖音(TikTok)的移动端短视频应用,展现了......
  • 深入理解Kubernetes网络:从原理到网络组件
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言K8s网络的实现原理默认网络模式常见网络组件1.Flannel2.Calico3.WeaveNetIngress的使用Ingress的实现原理Ingress的YAML示例使用场景查看所用网络组件不单独配置网络组件的影响配置网......
  • 【赵渝强老师】基于大数据组件的平台架构
      在了解了大数据各个生态圈所包含的组件及其功能特性后,就可以利用这些组件来搭建一个大数据平台从而实现数据的存储和数据的计算。下图展示了大数据平台的整体架构。  视频讲解如下:大数据平台的Lambda架构大数据平台的Kappa架构  大数据平台的......
  • Tauri2.0+Vite5聊天室|vue3+tauri2+element-plus仿微信|tauri聊天应用
    原创tauri2.0+vue3+pinai2仿QQ/微信客户端聊天Exe程序TauriWinChat。tauri2-vue3-winchat自研vite5+tauri2.0+vue3setup+element-plus跨平台仿QQ|微信桌面端聊天软件。全新封装tauri2多开窗口管理、自定义圆角阴影窗体。实现聊天、通讯录、收藏、我的、朋友圈/小视频等模块。......
  • 鸿蒙(HarmonyOS)组件化路由框架——Navigation的路由管理
    Navigation介绍Navigation简介Navigation:路由导航的根视图容器,一般作为页面(@Entry)的根容器去使用,包括单页面(stack)、分栏(split)和自适应(auto)三种显示模式。Navigation组件适用于模块内和跨模块的路由切换,通过组件级路由能力实现更加自然流畅的转场体验,并提供多种标题栏样式......
  • 移动端tree组件父子组件联动。
     <!--*@Author:yeminglong*@Date:2024-09-2710:14:30*@LastEditors:yeminglong*@LastEditTime:2024-09-2716:49:05*@Description:--><script>importTreeItemfrom'@/views/test/TreeItem.vue'exportdefault{ name:&#......
  • antv x6 注册vue组件 响应传值
    使用antvx6vue组件创建节点信息-当节点过于复杂可以考虑,避免使用markup\attr过于复杂  官网antv-vue组件示例1、使用inject接收父组件传值import{Graph}from'@antv/x6'import{register}from'@antv/x6-vue-shape' importTestNodefrom'./test1.vue'......
  • vue3 vxe-grid 通过数据库返回的列信息,生成columns,并且其中有一列是img类型,进行slots
    1、一般我们写死的列信息的时候,会这样定义:2、然后我们在template里面,这样这样写slots格式化部分:这样表格中就会展示出一张图片,并且,我们点击了可以查看大图。3、那么我们从数据库中返回的列,应该如何去写:letfields={field:item.fieldname,......