在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-loader
config.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-requires
const path = require('path')
解决方法三
使用import(node10一下不支持)
import path from 'path'
import整个目录
如要使用多个svg,那在文件里添加几次svg,使用几次use,在ts里import几次即可,但这样很麻烦,可以引入一个目录,把ts里的代码改成如下
<script lang="ts">
// eslint-disable-next-line no-undef
let 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>
写代码的思路:先实现功能,然后再重构,封装