[英]Vue.js can't toggle a font-awesome icon
I am trying to toggle a font awesome icon based on a boolean value but it seems that the font-awesome icon remains on the screen after it is drawn:我正在尝试根据布尔值切换字体真棒图标,但似乎字体真棒图标在绘制后仍保留在屏幕上:
https://jsfiddle.net/50wL7mdz/200312/ https://jsfiddle.net/50wL7mdz/200312/
HTML: HTML:
<script src="https://unpkg.com/vue"></script>
<script defer src="https://use.fontawesome.com/releases/v5.0.8/js/all.js" integrity="sha384-SlE991lGASHoBfWbelyBPLsUlwY1GwNDJo3jSJO04KZ33K2bwfV9YBauFfnzvynJ" crossorigin="anonymous"></script>

<div id="app">
<input v-model="marked" type="checkbox"/>
<i v-if="marked" class="far fa-check-square"></i>
</div>
JS: JS:
new Vue({
el: '#app',
data: {
marked: false
}
})
Am I doing something wrong or is there a bug in font-awesome or vue.js?我做错了什么还是 font-awesome 或 vue.js 中有错误?
I ran into this issue recently when using Vue.js 2.5.x with FontAwesome 5.5.x — the icon classes were not being updated as expected.我最近在使用 Vue.js 2.5.x 和 FontAwesome 5.5.x 时遇到了这个问题——图标类没有按预期更新。
After switching from the FontAwesome Web Fonts + CSS implementation to SVG + JS , the following code no longer worked:从 FontAwesome Web Fonts + CSS 实现切换到 SVG + JS后,以下代码不再起作用:
<i :class="[sortByFirstNameAsc ? 'fa-chevron-up' : 'fa-chevron-down', 'fa']"></i>
What would happen is that FontAwesome JavaScript would fire and wrap the <i>
tag and replace it with an SVG element, as in the following simplified example:会发生什么情况是 FontAwesome JavaScript 将触发并包装
<i>
标记并将其替换为 SVG 元素,如下面的简化示例所示:
<span data-v-2614dbd6="">
<svg data-v-2614dbd6="" class="svg-inline--fa fa-caret-up" ...">
...
</svg>
<!-- <i data-v-2614dbd6="" class="fa fa-caret-up"></i> -->
</span>
Unfortunately, the active class was being toggled on the inner, hidden <i>
tag and not the outer, visible SVG element.不幸的是,活动类是在内部隐藏的
<i>
标记而不是外部可见的 SVG 元素上切换的。
The workaround that restored the dynamic active class toggling was to wrap the FontAwesome icons in a span and use the v-show
directive , as illustrated in the following code snippet:恢复动态活动类切换的解决方法是将 FontAwesome 图标包装在一个 span 中并使用
v-show
指令,如以下代码片段所示:
<span v-show="sortByFirstNameAsc"><i class="fa fa-caret-up"></i></span>
<span v-show="sortByFirstNameDesc"><i class="fa fa-caret-down"></i></span>
The FontAwesome documentation now recommends using their Vue component to avoid conflicts in the DOM: FontAwesome 文档 现在建议使用他们的 Vue 组件来避免 DOM 中的冲突:
Compatibility Heads Up!
兼容性提示! If you are using Vue you need the vue-fontawesome package or Web Fonts with CSS.
如果您使用 Vue,则需要vue-fontawesome包或带有 CSS 的 Web 字体。
The SVG core package is helpful and recommended in the following cases: SVG 核心包在以下情况下很有帮助和推荐:
“i”标签在火灾转向 svg 后注释掉,使用一些 wrap <span v-if="marked"><i class="far fa-check-square"></i></span>
For some reason, you need to wrap the i
tag twice.出于某种原因,您需要将
i
标签包装两次。 For example, instead of this:例如,而不是这个:
<div v-if="condition">
<i class="fal fa-caret-left"></i>
</div>
<div v-else>
<i class="fas fa-caret-left"></i>
</div>
do this:做这个:
<template v-if="condition">
<div>
<i class="fal fa-caret-left"></i>
</div>
</template>
<template v-else>
<div>
<i class="fas fa-caret-left"></i>
</div>
</template>
Not entirely sure why you need to wrap it twice since I'd think you decouple the i
tag enough by wrapping it once, but it worked for me this way so there's apparently something else going on.不完全确定为什么需要将其包装两次,因为我认为您通过包装一次来充分解耦
i
标签,但它以这种方式对我有用,所以显然还有其他事情发生。
Also, keep in mind that the inner div
can't be replaced with template
for obvious reasons (template tags do not get rendered).另外,请记住,由于明显的原因,内部
div
不能用template
替换(模板标签不会被渲染)。
The Font Awesome library you used doesn't know about Vue.您使用的 Font Awesome 库不了解 Vue。 It takes the
<i>
that you wrote and turns it into an <svg>
, and at that point, it's been stolen from Vue.它将您编写的
<i>
转换为<svg>
,此时它已从 Vue 中窃取。 Vue no longer controls it. Vue 不再控制它。 The answer that Dialog gave was a good one: wrap it with a
<span>
. Dialog 给出的答案很好:用
<span>
包裹它。 But then you pointed out another scenario it doesn't work for.但是后来你指出了另一种情况它不起作用。
To solve your scenario where wrapping with a <span>
still doesn't work, use key="fa-sort-up"
.要解决使用
<span>
包装仍然不起作用的情况,请使用key="fa-sort-up"
。 This will force Vue to re-render the wrapper, at which point Font Awesome will update the icon.这将强制 Vue 重新渲染包装器,此时 Font Awesome 将更新图标。 Here's the updated jsFiddle for your example:
这是您示例的更新后的 jsFiddle :
<span key="fa-sort-up" v-if="sort && descending"><i class="fas fa-sort-up"></i></span>
<span key="fa-sort-down" v-else-if="sort"><i class="fas fa-sort-down"></i></span>
<span key="fa-sort" v-else><i class="fas fa-sort"></i></span>
You can use anything you want for the key, as long as it's unique.您可以使用任何您想要的密钥,只要它是唯一的。
Toggle a checkbox in vue with FontAwesome使用 FontAwesome 在 vue 中切换复选框
<style>
.fa-check-square::before {
color: green;
}
</style>
<script>
Vue.component('some',
{
data:
function() {
return{
isclick: false
}
},
methods: {
isClicked: function() {
this.isclick = !this.isclick;
}
},
template: '<div id="test" v-on:click="isClicked">' +
'<i v-if="isclick" class="fa fa-check-square" style="font-size: 40px;"></i>' +
'<i v-if="!isclick" class="far fa-square" style="font-size: 40px;"></i>' +
'</div>'
});
</script>
<div id="componentsDemo">
<some></some>
<some></some>
<some></some>
<some></some>
</div>
<script>
new Vue({ el: '#componentsDemo' });
</script>
I fixed this by creating a template for each icon, then loading either template conditionally based on a boolean.我通过为每个图标创建一个模板来解决这个问题,然后根据布尔值有条件地加载任一模板。
Here's my main template:这是我的主要模板:
<div v-if="minimised"> <maximise-icon> </maximise-icon> </div> <div v-if="!minimised"> <minimise-icon> </minimise-icon> </div>
Then just create the icons like so:然后像这样创建图标:
FontAwesomeConfig = { autoReplaceSvg: 'nest' }//important addition! Vue.component('minimise-icon', { template: ` <i class="fas fa-minus "></i> ` }) Vue.component('maximise-icon', { template: ` <i class="fas fa-plus "></i> ` })
If there's a more elegant way I'm all ears!如果有更优雅的方式,我会全神贯注!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.