【问题标题】:Feather icons usage in Vue.JSVue.JS 中的羽毛图标使用
【发布时间】:2020-03-01 19:52:33
【问题描述】:

我一直在尝试在一个新的 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 文件中,但问题仍然存在。

我猜这与 i 上的 data-feather 属性有关调用羽毛图标所需的标记。

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

更新 1: 根据@yuriy636 的建议,我在我的App 组件中导入了羽毛图标,然后在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 的模块有助于在 vue 中使用羽毛图标。只需安装它,导入它并使用它。 这似乎解决了这个问题。

【问题讨论】:

  • 尝试调用feather.replace()(好吧,为此您必须命名羽毛导入),如文档github.com/colebemis/feather#quick-start 中所述。你可以把它放在mounted 钩子里。
  • @yuriy636 非常感谢,您的解决方案有效。我照你说的做了,并在我的 App.vue 组件中导入了羽毛,然后调用了 mount 中的 replace 方法。我将编辑我的原始帖子以反映更改。非常感谢!
  • 仅供参考,您可能想改用github.com/mage3k/vue-feather-icon。与 Vue 集成似乎比尝试在正确的时间调用 feather.replace 更容易。 (我认为如果组件更新,mounted 钩子还不够用?)
  • (更新图标,也就是。)
  • 对于可能偶然发现这一点的其他人,一旦你调用了feather.replace,原始元素就消失了,因此 Vue 无法更新它。例如,您不能执行 &lt;i v-bind:data-feather="iconName"&gt;&lt;/i&gt; 之类的操作并期望图标更新。 (这适用于直接使用feather-iconsvue-feather-icon 大概与 Vue 很好地集成。)

标签: vue.js icons vuejs2 custom-data-attribute


【解决方案1】:

总结评论线程并为后人提出另一种解决方案:

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

以下是使用“香草”feather-icons 而不遇到上述问题的更好方法。在这里,我们使用调用 feather.toSvg 的计算属性,使用适当的图标 SVG 动态更新 div 的 HTML 内容:

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

【讨论】:

  • 谢谢!我只想补充一点,feather.toSvg() 已弃用,我们应该改用feather.icons[name].toSvg()
【解决方案2】:

这也可以作为一个功能组件来完成,您可以使用图标名称来简单地选择要呈现的 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>

【讨论】:

    猜你喜欢
    • 2018-10-06
    • 1970-01-01
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 2020-09-12
    • 1970-01-01
    • 2019-06-20
    • 2012-11-11
    相关资源
    最近更新 更多