Feather icons usage in Vue.JS Feather icons usage in Vue.JS vue.js vue.js

Feather icons usage in Vue.JS


Summarizing the comment thread and presenting another solution for posterity:

  1. The issue with the original code is that there's a missing call to feather.replace, which finds all the elements with data-feather attributes and replaces them with the appropriate icon's SVG.
  2. Calling feather.replace in the mounted hook is good enough for simple use cases, but it doesn't allow for icons changing. (In general, it strikes me as a bad idea to let non-Vue code modify the HTML you're using Vue to render.) E.g., <i v-bind:data-feather="iconName"></i> isn't going to allow for subsequent updates.
  3. vue-feather-icon appears to be a project that integrates better with Vue.

Below is a better way to use "vanilla" feather-icons without running into the above issues. Here, we're dynamically updating the HTML content of a div with the appropriate icon SVG by using a computed property that calls feather.toSvg:

<template>  <div id="app">    <h1>{{ message }}</h1>    <div v-html="iconSvg"></div>    <button @click="clicky">Click me</button>  </div></template><script>import feather from 'feather-icons'export default {  name: 'app',  data: function () {    return {      message: 'Hello, World!',      icon: 'flag'    }  },  computed: {    iconSvg: function () {      return feather.toSvg(this.icon)    }  },  methods: {    clicky: function () {      this.message = 'clicked'      this.icon = 'circle'    }  }}</script>


This can also be done as a functional component, and you can use the icon-names to simply pick which svg to render.

You can also swap out feathers and use another svg-sprite

// Usage        <div class="flex items-center p-2 mt-2 bg-white">      <x-svg icon="log-out" class="w-4 h-4" />    </div> // x-svg.vue    <template functional>      <svg        fill="none"        :viewBox="props.viewBox"        :class="['stroke-' + props.stroke, data.class, data.staticClass]"        class="inline-flex w-4 h-4 text-gray-500 stroke-current hover:text-gray-900 group-hover:text-gray-900"        stroke-linecap="round"        stroke-linejoin="round"        :ref="data.ref"        :style="[data.style, data.staticStyle]"        v-bind="data.attrs"        v-on="listeners"      >        <use :href="require('@/assets/img/feather-sptite.svg') + '#' + props.icon" />      </svg>    </template>    <script>    export default {      props: {        icon: {          type: String,          default: 'alert-circle'        },        stroke: {          type: Number,          default: 1,          validator(v) {            const sizes = [0.5, 1, 1.5, 2, 2.5]            return sizes.includes(v)          }        },        viewBox: {          type: String,          default: '0 0 24 24'        }      }    }    </script>