Search code examples
vue.jsfont-awesomebulma

Font Awesome not updating properly with vue


I'm trying to make a clickable "star" icon using font-awesome with bulma, switching between regular and solid styles (fas and far) in Vue, to achieve this I have the following component:

<template>
    <span v-if="isStarred" class="icon starred config-icon clickable-text" @click="unstar">
        <i class="far fa-star" title="Unstar Ranking"/>
    </span>
    <span v-else class="icon unstarred config-icon clickable-text" @click="star">
        <i class="fas fa-star" title="Star Ranking"/>
    </span>
</template>

The value isStarred is being updated properly and the span elements are updating accordingly. However the i element with the icon doesn't update until I fully reload the page.

I was able to make this work with v-show instead of v-if but I don't understand why this wouldn't work.


Solution

  • Vue tries to render elements as efficiently as possible, often re-using them instead of rendering from scratch. This isn’t always desirable though, so Vue offers a way for you to say, “These two elements are completely separate - don’t re-use them.” Add a key attribute with unique values:

    <i class="far fa-star" title="Unstar Ranking" key="unstared"/>
    ...
    <i class="fas fa-star" title="Star Ranking" key="stared"/>
    

    Now those i elements will be rendered from scratch each time you toggle.

    You can also update your classes with class binding:

    <span v-if="isStarred" v-bind:class="{starred: isStarred, unstarred: !isStarred}" class="icon config-icon clickable-text" @click="toggleStar">
        <i v-bind:class="{far: isStarred, fas: !isStarred}" class="fa-star" v-bind:title="title"/>
    </span>