webpack中封装svg组件以及使用

402 阅读1分钟

在webpack中处理svg以及封装

上才艺!

vue.config.js

引入path模块:
const path = require("path");
function resolve(dir) {
  return path.join(__dirname, dir);
}
module.exports = defineConfig({
  transpileDependencies: true,
  chainWebpack: (config) => {
    config.resolve.alias.set("~", resolve("./src"));

   /*
    定义一个名为 svg的规则,忽略 src/assets/svg 下的文件;
   */
config.module.rule("svg").exclude.add(resolve("src/assets/svg")).end();

/**
    .rule('icons') 定义一个名为 icons的规则
    
    .test(/\.svg$/) 匹配 .svg后缀的文件
    
    .include.add(resolve("src/assets/svg")) 该规则只在 src/assets/svg 下起作用
    
    .end() 结束链式调用,返回当前对象
    
    .use("svg-sprite-loader") 添加一个 loader
    
    .loader("svg-sprite-loader") 添加一个具体loader
    定义loader的规则
    .options({
        symbolId: "icon-[name]",
      })
      
*/
    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve("src/assets/svg"))
      .end()
      .use("svg-sprite-loader")
      .loader("svg-sprite-loader")
      .options({
        symbolId: "icon-[name]",
      })
      .end();
  },
});
svg组件:

image.png

定义组件 svg-icon.vue

<template>
//判断是否为外部链接,如果为外部链接直接使用 img 进行展示
  <img v-if="isExternal" :src="icon" alt="" />
  //否则 使用 svg
  <svg v-else>
    <use :xlink:href="iconName" />
  </svg>
</template>

<script setup>
import { computed, defineProps } from "vue";
//外部传入的 svg名称
const props = defineProps({
  icon: {
    type: String,
    required: true,
  },
});
//匹配是否为外链
const isExternal = computed(() =>
  /^(https?:\/\/[^\s/$.?#].[^\s]*)$/i.test(props.svgName)
);
//拼接名称
const iconName = computed(() => `#icon-${props.icon}`);
</script>

<style scoped></style>

svg-icon.js

//导入 svg-icon组件
import svgIconVue from "./svg-icon.vue";
/**
 * 使用webpack中提供的方法,导入指定文件夹下的资源
 * require.context方法可以传入三个参数:
 * 1、指定要搜索的目录
 * 2、是否递归搜索子目录
 * 3、匹配文件的正则表达式
 *  */ 
const svgRequire = require.context("../../assets/svg", false, /\.svg$/);
/**
 * svgRequire返回的是一个函数,在函数的属性中添加了 keys 方法,该方法可以返回所有匹配的文件名数组。
 * 可以调用svgRequire方法,这个返回传入 路径会返回一个指定路径的文件,for循环导入文件,存在webpack缓存中,便于loader解析
 *
 * */
svgRequire.keys().forEach((svgIconVue) => svgRequire(svgIconVue));

/**
 * default方法,可以接收一个参数,即当前的Vue实例,在这里注册组件
 * */ 
export default (app) => {
  app.component("svg-icon", svgIconVue);
};

main.js

import { createApp } from "vue";
import App from "./App.vue";
import svgIcon from "~/components/svg-icon/svg-index.js";
createApp(App).use(svgIcon).mount("#app");


使用:
  <svg-icon icon="https://res.lgdsunday.club/vip.svg"></svg-icon>
  <svg-icon icon="min-car"></svg-icon>
  <svg-icon icon="jingche"></svg-icon>

##### vite版本:

更新中...