VUE中的SVG

梁丘亦
2023-12-01


更新于:2023-02-13

vue2+webpack中的svg

依赖项

“svg-sprite-loader”: “^4.1.6”
“vue”: “^2.6.10”

vue.config.js配置

const path = require('path')

function resolve(dir) {
  return path.join(__dirname, './', dir)
}

module.exports = {
  chainWebpack: config => {
    // svg rule loader
    const svgRule = config.module.rule('svg') // 找到svg-loader
    svgRule.uses.clear() // 清除已有的loader, 如果不这样做会添加在此loader之后
    svgRule.exclude.add(/node_modules/) // 正则匹配排除node_modules目录
    svgRule // 添加svg新的loader处理
      .test(/\.svg$/)
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })

    // 修改images loader 添加svg处理
    const imagesRule = config.module.rule('images')
    imagesRule.exclude.add(resolve('src/assets/img/svg'))
    config.module
      .rule('images')
      .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
  }
}

assets/img/index.js加载svg

const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('./svg', false, /\.svg$/)
requireAll(req)

assets/img/svg

这里放svg图片

main.js引入

import '@/assets/img/index.js'

svgIcon.vue展示组件

<template>
  <svg :class="svgClass" aria-hidden="true">
    <use :xlink:href="iconName"/>
  </svg>
</template>

<script>
export default {
  name: 'SvgIcon',
  props: {
    iconClass: {
      type: String,
      required: true
    },
    className: {
      type: String,
      default: ''
    }
  },
  computed: {
    iconName () {
      return `#icon-${this.iconClass}`
    },
    svgClass () {
      if (this.className) {
        return 'svg-icon ' + this.className
      } else {
        return 'svg-icon'
      }
    }
  }
}
</script>

<style scoped>
.svg-icon {
  width: 16px;
  height: 16px;
  fill: currentColor;
}
</style>

svg.vue中使用

<template>
  <div class="svg-demo">
    <ul>
      <li v-for="(name, index) in name" :key="index">
        <svg-icon :iconClass="name"></svg-icon>
      </li>
    </ul>
  </div>
</template>
<script>
import svgIcon from "./svgIcon";
export default {
  name: "mysvg",
  components: { svgIcon },
  data() {
    return {
      name: ["wallet", "setting"]
    };
  }
};
</script>
<style lang="scss">
.svg-demo {
  text-align: center;
  ul,
  li {
    list-style: none;
    padding: 0;
    margin: 0;
    line-height: 2;
  }
}
</style>

vue3+vite中的svg

依赖项

“vite-plugin-svg-icons”: “^2.0.1”
“vue”: “^3.2.45”
“vite”: “^4.0.0”

vite.config.js配置

import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
import path from 'path';

export default defineConfig({
  plugins: [
    createSvgIconsPlugin({
      // Specify the icon folder to be cached
      iconDirs: [path.resolve(process.cwd(), 'src/assets/img/svg')],
      // Specify symbolId format
      symbolId: 'icon-[name]',
      /**
       * custom dom id
       * @default: __svg__icons__dom__
       */
      customDomId: '__svg__icons__dom__',
    })]
})

assets/img/svg

这里放svg图片

mian.js引入

import 'virtual:svg-icons-register';

svgIcon.vue展示组件

<template>
  <svg :class="svgClass" aria-hidden="true">
    <use :xlink:href="iconName" />
  </svg>
</template>

<script setup>
import { computed } from "vue";

const props = defineProps({
  iconClass: {
    type: String,
    required: true,
  },
  className: {
    type: String,
    default: "",
  },
});

const iconName = computed(() => {
  return `#icon-${props.iconClass}`;
});

const svgClass = computed(() => {
  if (props.className) {
    return "svg-icon " + props.className;
  } else {
    return "svg-icon";
  }
});
</script>

<style scoped>
.svg-icon {
  width: 16px;
  height: 16px;
  fill: currentColor;
}
</style>

svg.vue中使用

<template>
  <div class="svg-demo">
    <ul>
      <li v-for="(name, index) in svgName" :key="index">
        <SvgIcon :iconClass="name"></SvgIcon>
      </li>
    </ul>
  </div>
</template>
<script setup>
import SvgIcon from "../components/svgIcon.vue";
const svgName = ["wallet", "setting"];
</script>
<style lang="scss">
.svg-demo {
  text-align: center;
  ul,
  li {
    list-style: none;
    padding: 0;
    margin: 0;
    line-height: 2;
  }
}
</style>
 类似资料: