vue 使用svg

webpack 使用插件

npm i --save-dev svg-sprite-loader@6.0.9

 

vue.config.js

const path = require('pavueth');
function resolve(dir) {
  return path.join(__dirname, dir);
}

module.exports = {
  chainWebpack(config) {
    // 设置 svg-sprite-loader
    // config 为 webpack 配置对象
    // config.module 表示创建一个具名规则,以后用来修改规则
    config.module
      // 规则
      .rule('svg')
      // 忽略
      .exclude.add(resolve('src/icons'))
      // 结束
      .end();
    // config.module 表示创建一个具名规则,以后用来修改规则
    config.module
      // 规则
      .rule('icons')
      // 正则,解析 .svg 格式文件
      .test(/\.svg$/)
      // 解析的文件
      .include.add(resolve('src/icons'))
      // 结束
      .end()
      // 新增了一个解析的loader
      .use('svg-sprite-loader')
      // 具体的loader
      .loader('svg-sprite-loader')
      // loader 的配置
      .options({
        symbolId: 'icon-[name]',
      })
      // 结束
      .end();
  },
};

 

放置svg

 

 icon/index.js

import SvgIcon from '@/components/SvgIcon';

// https://webpack.docschina.org/guides/dependency-management/#requirecontext
// 通过 require.context() 函数来创建自己的 context
const svgRequire = require.context('./svg', false, /\.svg$/);
// 此时返回一个 require 的函数,可以接受一个 request 的参数,用于 require 的导入。
// 该函数提供了三个属性,可以通过 require.keys() 获取到所有的 svg 图标
// 遍历图标,把图标作为 request 传入到 require 导入函数中,完成本地 svg 图标的导入
svgRequire.keys().forEach((svgIcon) => svgRequire(svgIcon));

export default (app) => {
  app.component('svg-icon', SvgIcon);
};

 

main.js

import installIcons from '@/icons';

const app = createApp(App);
installIcons(app);

 

 

 

<template>
  <div
    v-if="isExternal"
    :style="styleExternalIcon"
    class="svg-external-icon svg-icon"
    :class="className"
  />
  <svg v-else class="svg-icon" :class="className" aria-hidden="true">
    <use :xlink:href="iconName" />
  </svg>
</template>

<script setup>
import { isExternal as external } from '@/utils/validate';
import { defineProps, computed } from 'vue';
const props = defineProps({
  // icon 图标
  icon: {
    type: String,
    required: true,
  },
  // 图标类名
  className: {
    type: String,
    default: '',
  },
});

/**
 * 判断是否为外部图标
 */
const isExternal = computed(() => external(props.icon));
/**
 * 外部图标样式
 */
const styleExternalIcon = computed(() => ({
  mask: `url(${props.icon}) no-repeat 50% 50%`,
  '-webkit-mask': `url(${props.icon}) no-repeat 50% 50%`,
}));
/**
 * 项目内图标
 */
const iconName = computed(() => `#icon-${props.icon}`);
</script>

<style scoped>
.svg-icon {
  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>

使用

 

 <svg-icon id="guide-lang" icon="language" />

 

调整svg颜色

  ::v-deep .svg-icon {
    color: #e2e2e2;
  }

 

posted @ 2021-12-29 18:03  real_zwj  阅读(103)  评论(0编辑  收藏  举报