Feather icons usage in Vue.JS

11,535

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>
Share:
11,535
Kyle Sentient
Author by

Kyle Sentient

Updated on June 29, 2022

Comments

  • Kyle Sentient
    Kyle Sentient almost 2 years

    I've been trying to use feather-icons in a new vue project. I first initialized the project using the vue-clie tools:

    vue init webpack
    

    once done, I ran:

    npm install
    npm run dev
    

    After that I installed feather-icons through npm as follows:

    npm install --save feather-icons
    

    Once done, I tried using the icons by importing the module in my main.js file:

    main.js:

    import 'feather-icons'
    
    import Vue from 'vue'
    import App from './App'
    import router from './router'
    
    Vue.config.productionTip = false
    
    new Vue({
      el: '#app',
      router,
      template: '<App/>',
      components: {
        App
      }
    })
    

    Then I tried using an icon in a Hello component:

    Hello.vue:

    <template>
      <div>
        <h1> Hello World!</h1>
        <i data-feather="flag"></i>
      </div>
    </template>
    
    <script>
      export default {
        name: 'hello',
        data() {
          return {
            msg: 'Welcome to Your Vue.js App'
          }
        }
      }
    
    </script>
    <style>
    </style>
    

    No error is detected during execution, yet the icon set refuses to work. I've tried including the feather-icons directly on the index.html file, but the problem persists.

    I'm guessing whatever is causing this is related to the data-feather attribute on the i tag required to invoke feather-icons.

    I've been at it for almost a couple hours, but nothing I tried seems to work. Any help would be appreciated. Thanks.

    UPDATE 1: As per @yuriy636's suggestion, I imported feather-icons in my App component then called feather.replace() in mounted:

    App.vue:

    <template>
      <div id="app">
        <router-view></router-view>
      </div>
    </template>
    
    <script>
    
      import feather from 'feather-icons'
    
      export default {
        name: 'app',
    
        mounted() {
          feather.replace();
        }
      }
    
    </script>
    
    <style>
    </style>
    

    UPDATE 2:

    As pointed out by @smarx, there is a module named vue-feather-icons that facilitates the usage of feather-icons with vue. just install it, import it and use it. This seems to have solved the issue.