Nuxt JS svg-sprite-loader 的使用和 自定义 VUE组件 来处理svg图标icon

2020-04-27 17:12:54

参考地址 Nuxt JS 使用 svg-sprite-loader 和 自定义 VUE组件 来处理svg图标icon

使用 svg-sprite-loader 和 自定义 VUE组件 来处理svg图标icon

1.安装svg-sprite-loader

npm install svg-sprite-loader -D

2.配置文件nuxt.config.js添加loader

官方文档使用webpack进行配置 Nuxt extend

assets/icons/svg 目录是我存放svg文件的目录

*PS: 默认情况下 Nuxt 使用 vue-loader、file-loader 以及 url-loader 这几个 Webpack 加载器来处理文件的加载和引用。
对于不需要通过 Webpack 处理的静态资源文件,可以放置在 static 目录中。
所以需要排除其他加载器对SVG文件的处理 参考GitHub Issue Nuxtjs + Vue-svg-loader *

nuxt.config.js 看注释吧

export default {
    //something others
    build:{
        extend(config,context){
        // 排除 nuxt 原配置的影响,Nuxt 默认有vue-loader,会处理svg,img等
        // 找到匹配.svg的规则,然后将存放svg文件的目录排除
            const svgRule = config.module.rules.find(rule => rule.test.test('.svg'))
        svgRule.exclude = [resolve(__dirname, 'assets/icons/svg')]

        //添加loader规则
            config.module.rules.push({
                test: /\.svg$/, //匹配.svg
                include: [resolve(__dirname, 'assets/icons/svg')], //将存放svg的目录加入到loader处理目录
                use: [{ loader: 'svg-sprite-loader',options: {symbolId: 'icon-[name]'}}]
        }
        }
    }
}

3.创建SvgIcon.vue组件,包装SVG便于引用

创建 components/SvgIcon.vue

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

<script>
export default{
  name: 'SvgIcon',
  props: {
    iconClass: {
      type: String,
      required: true
    },
    className: {
      type: String,
      default: ''
    }
  },
  computed: {
    isExternal() {
      return /^(https?:|mailto:|tel:)/.test(this.iconClass)
    },
    //通过iconClass 获取svg文件名
    iconName() {
      return `#icon-${this.iconClass}`
    },
    svgClass() {
      if (this.className) {
        return 'svg-icon ' + this.className
      } else {
        return 'svg-icon'
      }
    },
    //返回url请求位置
    styleExternalIcon() {
      return {
        mask: `url(${this.iconClass}) no-repeat 50% 50%`,
        '-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
      }
    }
  }
}    
</script>

<style scoped>
.svg-icon {
  min-width: 1em;
  min-height: 1em;
  vertical-align: -0.15em;
  fill: currentColor;
  overflow: hidden;
}

.svg-external-icon {
  background-color: currentColor;
  mask-size: cover!important;
  display: inline-block;
}
</style>

4.增加插件(Nuxt plugin 使用 vue插件)加载SvgIcon.vue组件

Nuxt.js允许您在运行Vue.js应用程序之前执行js插件.
我们需要在程序运行前配置好这个插件。

创建 plugins/svg-icon.js

import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// Nuxt 默认@指向根目录 

// 注册组件
Vue.component('svg-icon', SvgIcon)
//预请求svg组件(通过之前的svg-sprite-loader加载)
const req = require.context('@/assets/icons/svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)

注册在nuxt.congfig.js中注册plugins/svg-icon.js插件 修改 nuxt.config.js

export default {
    //something others

    //增加 plugins 配置
    //nuxt 会在vue.js程序运行前,执行所有注册的插件
    plugins:{
        '@/plugins/svg-icon' //注册插件文件 
    },
    build:{
        extend(config,context){
        // 排除 nuxt 原配置的影响,Nuxt 默认有vue-loader,会处理svg,img等
        // 找到匹配.svg的规则,然后将存放svg文件的目录排除
            const svgRule = config.module.rules.find(rule => rule.test.test('.svg'))
        svgRule.exclude = [resolve(__dirname, 'assets/icons/svg')]

        //添加loader规则
            config.module.rules.push({
                test: /\.svg$/, //匹配.svg
                include: [resolve(__dirname, 'assets/icons/svg')], //将存放svg的目录加入到loader处理目录
                use: [{ loader: 'svg-sprite-loader',options: {symbolId: 'icon-[name]'}}]
        }
        }
    }
}

5.页面中使用

下载SVG图标到 asset/icons/svg/blog.svg 然后在vue 模板中使用

<template>
 <!-- icon-class 的值,即svg文件名  -->
 <svg-icon icon-class="blog" />
</template>


  • 2020-02-22 17:45:43

    tweenjs简单快速学习

    tweenjs 是使用 JavaScript 中的一个简单的补间动画库,支持数字、对象的属性和 CSS 样式属性的赋值。 tweenjs 以平滑的方式修改元素的属性值,需要传递给 tween 要修改的值、动画结束时的最终值和动画花费时间(duration),之后 tween 引擎就可以计算从开始动画点到结束动画点之间值,从而产生平滑的动画效果。

  • 2020-02-22 17:47:12

    easeJs入门学习教程

    createjs中包含以下四个部分: EaselJS:用于 Sprites、动画、向量和位图的绘制,创建 HTML5 Canvas 上的交互体验(包含多点触控) TweenJS:用于做动画效果 SoundJS:音频播放引擎 PreloadJS:网站资源预加载

  • 2020-02-22 17:54:59

    最新FullCalendar中文文档

    Fullcalendar是一款用来管理日程安排、工作计划的日历工具,它功能非常强大而且非常实用。而目前网络上没有很好的中文文档,为了更好的和大家分享Fullcalendar的相关使用,即日起计划将Fullcalendar的英文文档翻译成中文版。

  • 2020-02-22 17:57:05

    nuxtjs支持api接口,serverMiddleware

    Who can’t relate to this: You’ve built a small portfolio page for someone, maybe a company, a friend or yourself. And the only API endpoint you’d need is one for a form. What now? Scaffolding a new service just for this one endpoint?

  • 2020-02-22 17:59:34

    FullCalendar插件的基本使用带详细配置翻译

    前段时间,一直在开发考勤系统,当时为满足设计的需求,选了好几个插件,最后决定采用Fullcanlendar的插件。感觉这个插件可以满足现阶段的功能开发需求

  • 2020-02-22 18:03:10

    Vue组件中使用Sass或者Less全局变量

    本文以Sass做案例,Less的参考,基本配置大同小异。 假如我们有一个Sass的全局变量common.scss文件,路径 ../style/common.scss 代码如下:

  • 2020-02-23 23:27:26

    Nuxt.js 基础入门教程

    Nuxt.js 就是一个极简的 vue 版的 ssr 框架。基于它,我们可以快速开发一个基于 vue 的 ssr 单页面应用。

  • 2020-02-24 18:36:17

    百度地图做电子围栏总结

    需求:在地图上画出围栏,设置围栏信息后保存,生成围栏列表。全选时,地图视野可看到全部的围栏区域,单独勾选会调整地图视野到当前勾选的围栏。围栏区域的中心点要显示围栏名称。