Как элегантно использовать SVG в проектах vue

SVG Ресурсы изображений Icon Vue.js

1. Основное введение

  • Цель этой статьи — показать, как настроить и удобно использовать значки svg в проекте.
  • В этой статье в качестве примера взят проект vue, конечно, принцип использования в React в основном аналогичен.
  • Значок svg можно использовать непосредственно через тег img или как значок.
  • Эта статья относится к статье Xinxu:Введение в технологию SVG Sprite.
  • Код загружен на гитхаб:гитхаб-адрес.

2. Конфигурация

  1. Установите svg-спрайт-загрузчик. Проекты, созданные с помощью скаффолдинга vue-cli, по умолчанию будут использовать url-loader для обработки svg, поэтому его необходимо обработать:
{
    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
    loader: 'url-loader',
    options: {
      limit: 10000,                                      
      name: utils.assetsPath('img/[name].[hash:7].[ext]')
    }
}
  1. cnpm i -D svg-sprite-loader. Создайте новую папку svg под static, чтобы поместить svg, используемый в качестве значка, и используйте include, include и img, чтобы различать. Затем измените конфигурацию webpack.base.conf.js, чтобы svg-sprite-loader обрабатывал только файлы в static/svg, которые мы указываем:
  {
    test: /\.svg$/,
    loader: 'svg-sprite-loader',
    include: [resolve('static/svg')], // include => 只处理指定的文件夹下的文件
    options: {
        symbolId: 'icon-[name]'
    }
  },
  {
    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
    loader: 'url-loader',
    exclude: [resolve('static/svg')], // exclude => 不处理指定的文件夹下的文件
    options: {
      limit: 10000,
      name: utils.assetsPath('img/[name].[hash:7].[ext]')
    }
  }

3. Используйте

  1. Создайте папку svg в компонентах и ​​создайте файл Svg.vue:
  <svg :class="svgClass" aria-hidden="true">
    <use :xlink:href="iconName"></use>
  </svg>
  1. Создайте папку svgConfig в папке utils, создайте файл index.js и глобально зарегистрируйте компонент svg-icon.
Vue.component('svg-icon', SvgIcon)
  1. Используйте require.context для автоматического импорта файлов без их импорта по одному:
const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('./../../../static/svg/', true, /\.svg$/)
requireAll(req)

4. Выполнить в main.js:

import '@/utils/svgConfig'

На данный момент мы можем использовать его непосредственно в проекте:

<svg-icon icon-class="users" />

4. Оптимизация

  • Хотя svg-icon можно использовать и сейчас, когда нет возможности различить svg интуитивно, когда файлов svg много, будет долго и трудоемко, если вы сможете найти их только по одному. Чтобы облегчить нам поиск и использование svg, мы можем создать новую страницу списка svg.
  1. Создайте новый файл SvgList.vue в файле pages, iconsMap — это импортированный массив файлов svg, а метод handleClipboard — это метод копирования по щелчку, который реализуется путем установки буфера обмена (cnpm i -S clipboard):
<div class="icons-wrapper">
  <div v-for="item in iconsMap" :key="item" @click="handleClipboard(generateIconCode(item), $event)">
    <el-tooltip placement="top">
      <div slot="content">
        {{generateIconCode(item)}}
      </div>
      <div class="icon-item">
        <div>
          <span class="svg-wrap" @click.stop>
            <svg-icon :icon-class="item" />
          </span>
        </div>
        <span>{{item}}</span>
      </div>
    </el-tooltip>
  </div>
</div>
  1. Получите iconsMap, создайте папку svgConfig в папке utils и файл generateIconsView.js Конечно, если вы используете vuex, вы также можете сохранить его в состоянии в vuex:
const data = {
  state: {
    iconsMap: []
  },
  generate (iconsMap) {
    this.state.iconsMap = iconsMap
  }
}

export default data
  1. Сохраните данные в iconsMap:
  2. Используйте в SvgList.vue:
<script>
import icons from '@/utils/svgConfig/generateIconsView'
export default {
  name: 'icons',
  data () {
    return {
      iconsMap: []
    }
  },
  mounted () {
    const iconsMap = icons.state.iconsMap.map((i) => {
      return i.default.id.split('-')[1]
    })
    this.iconsMap = iconsMap
  }
}
</script>
  1. Добавьте подсказки и методы для копирования по клику (буфер обмена cnpm i -S), используемые в SvgList.vue:
 methods: {
    generateIconCode (symbol) {
      return `<svg-icon icon-class="${symbol}" />`
    },
    handleClipboard (text, event) {
      clipboard(text, event)
    }
}
  1. Добавьте информацию о маршрутизации SvgList.vue в маршрутизацию, и эффект страницы будет следующим: