在https://www.iconfont.cn/下载svg格式图标,在项目的assets目录新建icons文件夹,导入图标
import 图片报错
import x from '@/assets/icons/money.svg'
解决办法: 在shims-vue.d.ts文件里添加
declare module '*.svg' {const content: string;export default content;}
使用svg-sprite-loader
安装
npm install svg-sprite-loader -D或yarn add --dev svg-sprite-loader
在vue.config.js中配置以下代码
const path = require('path');module.exports = {lintOnSave: false,chainWebpack: config => {const dir = path.resolve(__dirname, 'src/assets/icons')config.module.rule('svg-sprite').test(/\.svg$/) // 以.svg结尾.include.add(dir).end() // 包含icons目录.use('svg-sprite-loader').loader('svg-sprite-loader').options({extract: false}).end() // 配置svg-sprite-loaderconfig.plugin('svg-sprite').use(require('svg-sprite-loader/plugin'), [{plainSprite: true}]) // 配置插件config.module.rule('svg').exclude.add(dir) // 其他svg loader排除icons目录}};
svg-sprite-loader会把svg变成symbol,symbol对应的id为svg的文件名,并在symbol外套一个svg,在body里生成。配置成功后,重新yarn serve, 可以看到body里多了svg和symbol标签
要使用svg,则在对应页面的template部分写以下代码
‘#xxx’是对应svg的id
<template><svg><use xlink:href="#xxx"/></svg></template>
eslint报错处理
解决方法一
在eslintrc.js文件的rules里添加
rules: {'@typescript-eslint/no-var-requires':0,},
解决方法二
用webstorm的提示添加注释
// eslint-disable-next-line @typescript-eslint/no-var-requiresconst path = require('path')
解决方法三
使用import(node10一下不支持)
import path from 'path'
import整个目录
如要使用多个svg,那在文件里添加几次svg,使用几次use,在ts里import几次即可,但这样很麻烦,可以引入一个目录,把ts里的代码改成如下
<script lang="ts">// eslint-disable-next-line no-undeflet importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);try {importAll(require.context('../assets/icons', true, /\.svg$/));//使用require} catch (error) {console.log(error);}export default {name: 'Icon'};</script>
封装icon
新建icon.vue
<template><svg class="icon"><use :xlink:href="'#'+name"/> <!-- 动态绑定 --></svg></template><script lang="ts">const importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);try {importAll(require.context('../assets/icons', true, /\.svg$/));} catch (error) {console.log(error);}export default {props:['name'], // 用props传图标名name: 'icon'};</script><style lang="scss" scoped>/* 拷贝iconfont官网帮助文档里的css */.icon {width: 1em; height: 1em;vertical-align: -0.15em;fill: currentColor;overflow: hidden;}</style>
在main.js注册全局component后,使用组件
<template><div class="nav"><router-link to="/labels"><icon name="label"/>标签</router-link></div></template>// 可通过.icon设置样式<style>.icon {width: 32px;height: 32px;}</style>
写代码的思路:先实现功能,然后再重构,封装
