美文网首页
Vue 加载 svg icon

Vue 加载 svg icon

作者: 随机昵称 | 来源:发表于2021-05-27 19:23 被阅读0次

    我们都知道SVG替代图片作为图标的好处,但如何能够方便的加载在VUE工程中呢;通过直接插入SVG代码方式画,当然是OK的,但这种方式是不是很LOW,一个两个还好,如果icon太多了,那就不好管理了;

    咋样才能更加友好便捷使用呢,这两天研究 2 种方式,原理都是提前加载 svg 模板到 body 中,然后在需要用到的 svg icon 的地方,用 use 标记去实例化对应的 svg ;见:http://know.webhek.com/svg/svg-symbol.html

    使用icon font等CDN方式在线加载:

    好处是不用下载到本地,不用管理svg文件,方便那是真的

    坏处就是如果我们需要 icon fillColor 根据 currentColor 更改而更改的话,就不好使了,因为通常来将,加载的 svg 都是有 fillColor 的,此时在引用的地方,使用 fill color 是无效的,如下图;所以可能需要准备多套资源,增加工作量,且资源多了也会对内存和加载速度有影响;当然也可以准备不带 fill 的资源,iconfont 官网说明里给了一个不带fill的链接,我自己反正是不知道怎么弄到 iconfont 上去;

    image

    使用svg-sprite-loader等插件本地加载

    好处当然是可以定制啦,多色也没问题,只是可能需要打开文件,去掉部分 fill 属性;这样在外面传入的 fill 才能生效;

    坏处当然是要本地维护这些资源了,而且需要搞定一些配置,才能快乐使用,这配置是真的没那么简单,这个后面我会讲到;


    下面我就讲讲如何使用吧

    1、使用 iconfont 等 CDN 链接方式加载模板;

    前面说了,这个是真的简单方便

    首先,默认在 iconfont 上的账户有资源啦;选择 Symbol,复制链接加到你的项目中;

    image image

    项目 run 起来后,在 body 中可以看到加载好的模板;

    image

    然后在需要使用的地方,插入代码

    <svg class="icon"><use xlink:href="#iconzu91-copy"></use></svg>

    代码中#iconzu91-copy为模板中对应的 symbol id 值;加载的效果如下:

    image

    是不是超简单;

    2、使用 svg-sprite-loader 等插件方式加载;

    • 首先当然是安装插件了,npm install svg-sprite-loader -D

    • 第 2 步,下载svg 放到工程目录下,我是放在这里的,大家随意,开心就好;

    image
    • 第 3 步,批量引用 svg 文件;

      在 svgicons 下新建一个 index.js,加入如下代码

    const context = require.context(".", false, /\.svg$/);
    const requireAll = (requireContext) => {
      return requireContext.keys().map(requireContext);
    };
    requireAll(context);
    

    webpack 关于 require.context 的解释,可以看一下;
    我就不解释了,水平有限,还是看官方文档吧;

    • 第 4 步,配置 webpack 下模块加载配置,配置的目的是要让 svg-sprite-loader 将对应的 svg 文件的模板编译加载到body中

    配置要分两种情况,看工程是用 vue cli 2 还是 3 及以上创建的了;

    cli2 的配置如下(cli3 的可以直接跳到 **cli3配置 **)

    需要在 webpack.base.conf.js 中的 module 下的 rules 下添加如下配置

    {
            test: /\.svg$/,
            loader: "svg-sprite-loader",
            include: [resolve("src/assets/svgicons")],
            options: {
              symbolId: "svg-[name]"
            }
    }
    

    这个意思是说,我们用 svg-sprite-loader 这个插件去加载 src/assets/svgicons 文件夹下所有的以 .svg 结尾的文件,并且模板中 symbol id 是以 svg- 开头,文件名称结尾;当然,这个前缀要不要都行;

    注意,rules 中,可能还有其他的 loader 会去处理 svg 的,我们可以在对应的插件 loader 下配置exclude: [resolve("src/assets/svgicons")],如我这里需要配置,这样 url-loader 就不会去处理编译对应文件加下的文件了;

    {
            test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
            loader: "url-loader",
            exclude: [resolve("src/assets/svgicons")],
            options: {
              limit: 10000,
              name: utils.assetsPath("img/[name].[hash:7].[ext]")
            }
    }
    

    完了后,就可以run 起来,然后就可以看到 body 中已加载好了模板;


    body 中 svg 模板.PNG
    cli3及以上的配置如下(cli2 的可以跳过这一步)

    首先在根目录新建 vue.config.js 文件,

    这个地方解释一下,配置同 cli2,只不过这里看起来是没有在 cli2 中显得那么直观;

    下面拆解下我自己是如何配置这部分的
    首先到 node_modules/@vue/cli-service/lib/config/base.js 下查看默认配置

    webpack base rules.PNG
    可以看到,默认处理 svg 文件的是 file-loader,这里我们把默认的svg的配置里加一个 exclude,同 cli2 中配置,这样 file-loader 和 我们将要设置的 svg-loader 就不会重复处理我们的src/assets/svgicons 下的 svg 文件;当然,我们也可以覆盖svg rule,这样所有的 svg 文件就会采用我们覆盖的 loader 去处理 svg 文件;

    新建一个规则配置

    /* eslint-disable */
    const path = require("path");// @ts-ignore
    /* eslint-enable */
    
    function resolve(dir) {
      // 路径可能与你的项目不同
      return path.join(__dirname, dir);
    }
    
    module.exports = {
      chainWebpack: (config) => {
        // exclude 配置默认的 svg 规则下不处理对应我定义的文件夹下的 svg 文件
        config.module.rule("svg").exclude.add(resolve("src/assets/svgicons")).end();
        // 新建一个 svgIcon rule,配置它的加载方式
        config.module
          .rule("svgIcon")
          .test(/\.svg$/)
          .use("svg-sprite")
          .loader("svg-sprite-loader")
          .options({
            symbolId: "svg-[name]",
          })
          .end()
          .include.add(resolve("src/assets/svgicons"))
          .end();
      },
    };
    

    覆盖配置如下

    module.exports = {
      chainWebpack: (config) => {
        // 先清除 uses,否则 svg 文件就会先被默认的 fileloader 处理一次,然后再被 svg-sqrite-loader 再处理一次
        config.module.rule("svg").uses.clear();
        config.module
          .rule("svg")
          .test(/\.svg$/)
          .use("svg-sprite")
          .loader("svg-sprite-loader")
          .options({
            symbolId: "svg-[name]",
          })
          .end()
          .include.add(resolve("src/assets/svgicons"))
          .end();
      },
    };
    

    完了后,就可以run 起来,然后就可以看到 body 中已加载好了模板;


    body 中 svg 模板.PNG
    • 第 5 步,看疗效:

    在需要使用 svg icon 的地方加入如下代码

    <svg class="svg-icon"> <use :xlink:href="svg-svg-on-dark" /> </svg>
    <svg class="svg-icon"> <use :xlink:href="svg-eye" /> </svg>
    

    成功加载


    image

    后面我会再研究下 vue-svg-loader 加载 svg icon

    相关文章

      网友评论

          本文标题:Vue 加载 svg icon

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