美文网首页
前端SVG图片自动化引入

前端SVG图片自动化引入

作者: tikeyc | 来源:发表于2024-12-31 22:39 被阅读0次
  • 以下有Vue3、Vue2

Vue3 ts

插件 vite-plugin-svg-icons

vite.config.ts

import path from 'path'
import { fileURLToPath, URL } from 'node:url'

import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import Components from 'unplugin-vue-components/vite'
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'
import legacy from '@vitejs/plugin-legacy'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'

// https://vitejs.dev/config/
export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, './')

  return {
    base: env.VITE_BASE_URL,
    plugins: [
      vue(),
      vueJsx(),
      Components({
        resolvers: [
          AntDesignVueResolver({
            importStyle: 'less' // css in js
          })
        ],
        version: 3
      }),
      createSvgIconsPlugin({
        iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
        symbolId: 'icon-[dir]-[name]'
      }),
      legacy({
        targets: ['ie > 11'],
        additionalLegacyPolyfills: ['regenerator-runtime/runtime']
      })
    ],
    resolve: {
      alias: {
        '@': fileURLToPath(new URL('./src', import.meta.url)),
        lodash: 'lodash-es'
      }
    },
    server: {
      host: '0.0.0.0',
      port: 3000,
      cors: true,
      proxy: {
        '/dev/api': {
          target: 'http://10.10.22.133:8580',
          // target: 'http://10.10.25.71',
          // target: 'http://10.10.25.83',
          changeOrigin: true,
          rewrite: (path) => path.replace(/^\/dev\/api/, '')
        }
      },
      hmr: { overlay: false }
    },
    build: {
      outDir: env.VITE_OUT_DIR,
      assetsDir: 'assets',
    }
  }
})

svg-icon.vue

import 'virtual:svg-icons-register';
<template>
  <svg aria-hidden="true" class="svg-icon" :style="style" v-bind="$attrs">
    <use :href="symbolId" :fill="color || '#333'" />
  </svg>
</template>

<script setup lang="ts">
import { isNumber } from 'lodash-es'
import { computed } from 'vue'
import px2rem from '@/utils/flexble'

const props = defineProps<{
  prefix?: string
  name: string
  color?: string
  size?: number | [number, number]
}>()

const symbolId = computed(() => `#${props.prefix || 'icon'}-${props.name}`)

const width = computed(() => {
  if (!props.size) return ''
  return isNumber(props.size) ? props.size : props.size[0]
})

const height = computed(() => {
  if (!props.size) return ''
  return isNumber(props.size) ? props.size : props.size[1]
})

const style = computed(() => {
  const style: { width?: string; height?: string } = {}
  if (width.value) style.width = px2rem(width.value) as string
  if (height.value) style.height = px2rem(height.value) as string
  return style
})
</script>

vue2

svg-icon.js

import Vue from "vue";
import SvgIcon from "@/components/SvgIcon/index.vue"; // svg component

// register globally
Vue.component("svg-icon", SvgIcon);

// 在svg-icon.js同层文件夹svg下引入svg图片
const req = require.context("./svg", true, /\.svg$/);
const requireAll = (requireContext) =>
  requireContext.keys().map(requireContext);
requireAll(req);

SvgIcon/index.vue

<template>
  <div
    v-if="isExternal"
    :style="styleExternalIcon"
    class="svg-external-icon svg-icon"
    v-on="$listeners"
  />
  <svg
    v-else
    :class="svgClass"
    aria-hidden="true"
    :style="styles"
    v-bind="$attrs"
    v-on="$listeners"
  >
    <use :xlink:href="iconName" />
  </svg>
</template>

<script>
// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
function isExternal(path) {
  return /^(https?:|mailto:|tel:)/.test(path);
}

export default {
  name: "SvgIcon",
  props: {
    iconClass: {
      type: String,
      required: true
    },
    className: {
      type: String,
      default: ""
    },
    size: {
      type: Number,
      default: 0
    },
    rotate: {
      type: Number,
      default: 0
    }
  },
  computed: {
    isExternal() {
      return isExternal(this.iconClass);
    },
    iconName() {
      return `#icon-${this.iconClass}`;
    },
    svgClass() {
      if (this.className) {
        return `svg-icon ${this.className}`;
      }
      return "svg-icon";
    },
    styleExternalIcon() {
      return {
        mask: `url(${this.iconClass}) no-repeat 50% 50%`,
        "-webkit-mask": `url(${this.iconClass}) no-repeat 50% 50%`
      };
    },
    styles() {
      let css = {};
      if (this.size) {
        css = {
          ...css,
          width: `${this.size}px`,
          height: `${this.size}px`
        };
      }
      if (this.rotate) {
        css = {
          ...css,
          transform: `rotate(${this.rotate}deg)`
        };
      }
      return css;
    }
  }
};
</script>

<style scoped>
.svg-icon {
  width: 16px;
  height: 16px;
  vertical-align: middle;
  fill: currentColor;
  overflow: hidden;
}

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


相关文章

  • SVG use使用

    平时使用svg,都是当成图片来使用,直接用img标签像引入图片一样引入svg。现在认识一下SVG Sprite技术...

  • 在React-Native中使用SVG图片

    React-Native是不能直接引入SVG图片的,但是我们可以借助react-native-svg和react-...

  • HTML常用的符号集

    前言 当下前端开发过程中,项目页面使用图标时一般不直接引入图片。因为不管你使用的是jpg,png还是svg,每个图...

  • 前端(7)vue引入svg图标

    自我从事前端工作以来,网页中加载图标时,常常会遇到以下问题: 图片无法放大,会失真; 在线icon开始的时候,觉得...

  • React-native 中Svg字体图标的使用

    1.需要引入的库: 2.将所需要的svg图片存入assets->SVG文件夹下,同级别建立脚本文件getSvg.j...

  • 小程序加载svg图片

    前言 小程序的组件中是没有支持SVG标签的。但是在前端小伙伴的实际开发中,UED经常提供SVG图片过来,如果不想用...

  • SVG用法

    常见引入svg的方法 .svg文件的常见结构: html页面中绘制svg的常见方法: 关于SVG的viewBox:...

  • laravel5.8简单图片上传(已封装完成)

    前端页面 控制器 图片上传已经封装好,直接调用就好.首先引入图片上传类 图片上传类

  • iOS-加载SVG类型的图片并且实现可点击长按功能

    首先介绍下该项目实现了那些功能 svg图片数据解析 绘制svg图片 svg图片按照区域设置不同颜色绘制图片.png...

  • ant desgin 如何使用自定义svg做icon

    场景 ui发svg发到大前端工程师的电脑本地,由大前端工程师上传图片到iconfont.cn上面,自己创建项目 u...

网友评论

      本文标题:前端SVG图片自动化引入

      本文链接:https://www.haomeiwen.com/subject/pdrbejtx.html