Vue.JS 中的羽毛图标使用情况

Feather icons usage in Vue.JS

我一直在尝试在一个新的vue项目中使用feather-icons。 我首先使用vue-clie工具初始化项目:

vue init webpack

完成后,我 运行:

npm install
npm run dev

之后我通过 npm 安装了 feather-icons 如下:

npm install --save feather-icons

完成后,我尝试通过在我的 main.js 文件中导入模块来使用图标:

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
  }
})

然后我尝试在 Hello 组件中使用图标:

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>

执行过程中未检测到错误,但图标集无法运行。我试过直接在 index.html 文件中包含羽毛图标,但问题仍然存在。

我猜造成这种情况的原因与 data-feather 属性有关 i 调用羽毛图标所需的标签。

我已经用了将近几个小时了,但我尝试过的任何东西似乎都不起作用。 任何帮助,将不胜感激。谢谢。

更新 1: 根据@yuriy636 的建议,我在 App 组件中导入了 feather-icons,然后在 mounted:

中调用了 feather.replace()

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>

更新 2:

正如@smarx 所指出的,有一个名为 vue-feather-icons 的模块可以促进羽毛图标的使用与视图。只需安装它,导入它并使用它。 这似乎已经解决了问题。

总结评论线程并为后代提供另一个解决方案:

  1. 原始代码的问题是缺少对 feather.replace 的调用,它会找到所有具有 data-feather 属性的元素并将它们替换为适当图标的 SVG。
  2. mounted 挂钩中调用 feather.replace 对于简单用例来说已经足够了,但它不允许更改图标。 (总的来说,让非 Vue 代码修改你正在使用 Vue 渲染的 HTML 是个坏主意。)例如,<i v-bind:data-feather="iconName"></i> 不允许后续更新。
  3. vue-feather-icon 似乎是一个与 Vue 集成得更好的项目。

下面是使用 "vanilla" feather-icons 而不 运行 解决上述问题的更好方法。在这里,我们通过使用调用 feather.toSvg:

的计算 属性 动态更新 div 的 HTML 内容和适当的图标 SVG
<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>

这也可以作为一个功能组件来完成,您可以使用图标名称来简单地选择要渲染的 svg。

您也可以换掉羽毛并使用另一个 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>