https://www.iconfont.cn/下载svg格式图标,在项目的assets目录新建icons文件夹,导入图标

import 图片报错

  1. import x from '@/assets/icons/money.svg'

解决办法: 在shims-vue.d.ts文件里添加

  1. declare module '*.svg' {
  2. const content: string;
  3. export default content;
  4. }

使用svg-sprite-loader

安装

  1. npm install svg-sprite-loader -D
  2. yarn add --dev svg-sprite-loader

在vue.config.js中配置以下代码

  1. const path = require('path');
  2. module.exports = {
  3. lintOnSave: false,
  4. chainWebpack: config => {
  5. const dir = path.resolve(__dirname, 'src/assets/icons')
  6. config.module
  7. .rule('svg-sprite')
  8. .test(/\.svg$/) // 以.svg结尾
  9. .include.add(dir).end() // 包含icons目录
  10. .use('svg-sprite-loader').loader('svg-sprite-loader').options({extract: false}).end() // 配置svg-sprite-loader
  11. config.plugin('svg-sprite').use(require('svg-sprite-loader/plugin'), [{plainSprite: true}]) // 配置插件
  12. config.module.rule('svg').exclude.add(dir) // 其他svg loader排除icons目录
  13. }
  14. };

svg-sprite-loader会把svg变成symbol,symbol对应的id为svg的文件名,并在symbol外套一个svg,在body里生成。配置成功后,重新yarn serve, 可以看到body里多了svg和symbol标签
image.png

要使用svg,则在对应页面的template部分写以下代码
‘#xxx’是对应svg的id

  1. <template>
  2. <svg>
  3. <use xlink:href="#xxx"/>
  4. </svg>
  5. </template>

eslint报错处理

解决方法一
在eslintrc.js文件的rules里添加

  1. rules: {
  2. '@typescript-eslint/no-var-requires':0,
  3. },

解决方法二
用webstorm的提示添加注释

  1. // eslint-disable-next-line @typescript-eslint/no-var-requires
  2. const path = require('path')

解决方法三
使用import(node10一下不支持)

  1. import path from 'path'

import整个目录

如要使用多个svg,那在文件里添加几次svg,使用几次use,在ts里import几次即可,但这样很麻烦,可以引入一个目录,把ts里的代码改成如下

  1. <script lang="ts">
  2. // eslint-disable-next-line no-undef
  3. let importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);
  4. try {
  5. importAll(require.context('../assets/icons', true, /\.svg$/));//使用require
  6. } catch (error) {
  7. console.log(error);
  8. }
  9. export default {
  10. name: 'Icon'
  11. };
  12. </script>

封装icon

新建icon.vue

  1. <template>
  2. <svg class="icon">
  3. <use :xlink:href="'#'+name"/> <!-- 动态绑定 -->
  4. </svg>
  5. </template>
  6. <script lang="ts">
  7. const importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);
  8. try {importAll(require.context('../assets/icons', true, /\.svg$/));} catch (error) {console.log(error);}
  9. export default {
  10. props:['name'], // 用props传图标名
  11. name: 'icon'
  12. };
  13. </script>
  14. <style lang="scss" scoped>
  15. /* 拷贝iconfont官网帮助文档里的css */
  16. .icon {
  17. width: 1em; height: 1em;
  18. vertical-align: -0.15em;
  19. fill: currentColor;
  20. overflow: hidden;
  21. }
  22. </style>

在main.js注册全局component后,使用组件

  1. <template>
  2. <div class="nav">
  3. <router-link to="/labels">
  4. <icon name="label"/>
  5. 标签
  6. </router-link>
  7. </div>
  8. </template>
  9. // 可通过.icon设置样式
  10. <style>
  11. .icon {
  12. width: 32px;
  13. height: 32px;
  14. }
  15. </style>

写代码的思路:先实现功能,然后再重构,封装