svg-icon组件封装

知识点
1、自己使用webpack搭建项目配置webpack是增加webpack.config.js
2、vue/cli搭建的webpack3以上的webpack改写是增加vue.config.js
官网对vue.config.js的介绍
https://cli.vuejs.org/zh/guide/webpack.html

vue.config.js中configureWebpack是进行简单的配置;用chainWebpack做高级配置;包括对loader的添加,修改;以及插件的配置

3、svg标签内部可以包裹的标签
https://www.w3school.com.cn/svg/svg_reference.asp
use元素是通过xlink:href属性,寻找要使用的元素的
<svg width="500" height="110"><use xlink:href="#shape" x="50" y="50" /></svg>
aria-hidden="true" 让这个元素对浏览器隐藏。
4、png是图片用img引入
在Firefox、Internet Explorer9、谷歌Chrome和Safari中,你可以直接在HTML嵌入SVG代码。
5、
require.context 建立请求的上下文
require.context(directory, useSubdirectories, regExp)
directory: 要查找的文件路径
useSubdirectories: 是否查找子目录
regExp: 要匹配文件的正则
6、svg-sprite-loader会把你的icon塞到一个个symbol中,symbol的id如果不特别指定,就是你的文件名。它最终会在你的html中嵌入这样一个svg,

关于原理原文:https://segmentfault.com/a/1190000015367490
场景:
公司出一套图标库,后缀svg,不想每次使用写重复的路径
<img src="/long/path/to/your/svg/icon.svg" />(这种引入是可以的)
要封装类似<el-icon name="icon-file-name"></el-icon>这种
思路:
1、每一个后缀为svg的图片展开的代码是

image.png

是已经绘制好的图形
2、使用use元素
use元素是SVG中非常强大,非常重要的一个元素,尤其在Web开发中,为何?
两点:
(1). 可重复调用;
(2). 跨SVG调用;
意识是通过use元素可以再次调用.svg文件进行页面展示
svg 和 use 的使用
<svg width="500" height="110"><use xlink:href="#shape" x="50" y="50" /></svg>
3、页面直接使用svg和use的代码
vue页面中

    <svg>
      <use xlink:href="#404"></use>
    </svg>

mian.js中引入对应的svg

import './svgs/404.svg';

loader要加入 webpack4配置

    chainWebpack: config => {
        config.module
            .rule('svg')
            .exclude.add(resolve('src/svgs'))// svgs文件目录
            .end()

        config.module
            .rule('svgs')// svgs文件目录
            .test(/\.svg$/)
            .include.add(resolve('src/svgs'))// svgs文件目录
            .end()
            .use('svg-sprite-loader')
            .loader('svg-sprite-loader')
    }

现在页面展示ok
4、需要将下面代码进行组件封装

    <svg>
      <use xlink:href="#404"></use>
    </svg>

5、不能在main.js中一行一行引入svg的文件,使用require.context尽力上下文全部引入

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

6、组件需要全局注册,并进行使用

具体代码如下:
封装svg-icon
1、.svg后缀的图标放入svgs文件夹中,svgs位于src目录下
2、创建svgIcon组件位于components中
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: 1em;
  height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}
</style>

在src下创建plugins文件夹,创建icon.js
icon.js

import Vue from 'vue'
import SvgIcon from '@/components/svgIcon'// svg组件

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

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

main.js中
import './plugins/icon'
在vue页面中使用
<svg-icon icon-class="user"></svg-icon>

svg需要loader进行解析
svg-sprite-loader -D

vue.config.js中的相关配置

const path = require('path')
function resolve (dir) {
    return path.join(__dirname, dir)
}
module.exports = {
    chainWebpack: config => {
        config.module
            .rule('svg')//这里不明白,为啥是svg
            .exclude.add(resolve('src/svgs'))
            .end()

        config.module
            .rule('svgs')// svgs文件目录
            .test(/\.svg$/)
            .include.add(resolve('src/svgs'))
            .end()
            .use('svg-sprite-loader')
            .loader('svg-sprite-loader')
            .options({
                symbolId: 'icon-[name]'
            })
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容