Vue.js does not have the ability to toggle a font-awesome icon

I am having trouble toggling a font awesome icon based on a boolean value. It seems that the font-awesome icon stays on the screen even after it is drawn:

Check out this link for reference

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:

new Vue({
  el: '#app',
  data: {
    marked: false
  }
})

Is there an issue in my code or could this be a bug in font-awesome or vue.js?

Answer №1

Encountered an issue recently while working with Vue.js 2.5.x and FontAwesome 5.5.x where the icon classes did not update as expected.

Switching from FontAwesome Web Fonts + CSS to SVG + JS caused a code snippet like this to stop functioning:

<i :class="[sortByFirstNameAsc ? 'fa-chevron-up' : 'fa-chevron-down', 'fa']"></i>

The problem was that FontAwesome JavaScript would replace the <i> tag with an SVG element, resulting in the active class being applied to the hidden <i> instead of the visible SVG.

To resolve this and restore dynamic class toggling, I needed to wrap the icons in a span and utilize the v-show directive:

<span v-show="sortByFirstNameAsc"><i class="fa fa-caret-up"></i></span>
<span v-show="sortByFirstNameDesc"><i class="fa fa-caret-down"></i></span>

FontAwesome documentation now suggests using their Vue component to prevent DOM conflicts:

Compatibility Heads Up! If you are using Vue, make sure to use thevue-fontawesome package or Web Fonts with CSS.

The SVG core package is recommended for various situations:

  • Subsetting icons for specific use
  • Use in larger integrations with frameworks like React, Angular, Vue, or Ember
  • Utilizing tools like Webpack, Rollup, or Parcel for bundling modules
  • As a UMD-style loader library such as RequireJS
  • For server-side rendering with CommonJS

Answer №2

After a blaze transforms into an svg, the "i" tag should be commented out and then wrapped in

<span v-if="marked"><i  class="far fa-check-square"></i></span>

Answer №3

When using Font Awesome with SVG, follow this tip.

If you find yourself needing to incorporate Font Awesome icons with SVG, make sure to wrap the i tag twice. Here's an example to illustrate:

<div v-if="condition">
  <i class="fal fa-caret-left"></i>
</div>
<div v-else>
  <i class="fas fa-caret-left"></i>
</div>

Rather than the above approach, try wrapping it like 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>

It may seem redundant to double-wrap the i tag, but for some reason, it is necessary to ensure proper functionality. This workaround worked for me, indicating that there might be additional factors at play.

Remember that replacing the inner div with template is not feasible due to rendering limitations associated with template tags.

Answer №4

The use of Font Awesome library in your project may cause conflicts with Vue's control. When you include an <i> tag, it gets converted to an <svg> by the library, which takes it out of Vue's jurisdiction. One solution suggested in a previous discussion on Stack Overflow was to wrap the icon with a <span>. However, if this method still doesn't work for your specific case, try adding a unique key like key="fa-sort-up" to force Vue to re-render and update the Font Awesome icon. Here's an example using this approach:

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

Remember to choose a unique key each time you need to trigger a re-render in Vue.

Answer №5

How to Toggle a checkbox using FontAwesome in Vue.js

<style>
  .fa-check-square::before {
    color: green; 
  }
</style>

<script>
  Vue.component('checkbox',
    {
      data: 
        function() {
          return{
            isChecked: false
          }
        },
      methods: {
        toggleCheckbox: function() {
          this.isChecked = !this.isChecked;
        }
      },
      template: '<div id="test" v-on:click="toggleCheckbox">' +
        '<i v-if="isChecked" class="fa fa-check-square" style="font-size: 40px;"></i>' +
        '<i v-if="!isChecked" class="far fa-square" style="font-size: 40px;"></i>' +
        '</div>'
    });

</script>

<div id="checkboxDemo">
  <checkbox></checkbox>
  <checkbox></checkbox>
  <checkbox></checkbox>
  <checkbox></checkbox>
</div>

<script>
  new Vue({ el: '#checkboxDemo' });
</script>

Answer №6

To solve this issue, I decided to streamline the process by generating a separate template for each icon. These templates are then loaded conditionally based on a boolean value.

Below is my primary template structure:

<div v-if="minimised">
    <maximise-icon>
    </maximise-icon>
</div>

<div v-if="!minimised">
    <minimise-icon>
    </minimise-icon>
</div>

Subsequently, creating the icons is straightforward:

FontAwesomeConfig = { autoReplaceSvg: 'nest' } // A critical 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 solution out there, I am open to suggestions!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Solving the problem of endless looping in JavaScript tree structures

i have been trying to create a tree structure in JavaScript. However, when I use the add_child function to add a child to an item in the elements array, it adds the child to all items in the elements array and their children, creating an infinite loop. I ...

What could be the reason for the checkbox not being selected in a React component

I'm currently working on integrating an autocomplete feature with checkboxes. Learn more here https://i.stack.imgur.com/YtxSS.png However, when trying to use the same component in final-form, I'm facing issues with checking my options. Why is t ...

Tips for overlaying an image on a div regardless of its height

(!) Although this question may seem repetitive, I have not been able to find a suitable solution in any of the previous 10 topics. I apologize for the inconvenience and am actively seeking a resolution to this unique situation; Allow me to outline the iss ...

How can I effectively handle extensive data parsing from a file using JavaScript?

Looking to optimize data parsing in JavaScript for a large file? I'm currently using JSON parse for a 250MB file, but it's too slow. Is there a faster method to extract a high volume of data without iterating through every character? The file con ...

Proper method for updating a component prop in Vue.js from within its method

Here is the code snippet for a Vue.js component: var list = Vue.component('list', { props: ['items', 'headertext', 'placeholder'], template: ` <div class="col s6"> <div class="search"> ...

jQuery is displaying fields inside the widget box that were supposed to have been removed

I am currently working on a project with a widget foldable box function called Metadata Widget. This widget displays certain fields, and I have added an import button to the side that calls upon the Metadata Widget and shows it. However, I have noticed tha ...

Passing the contents of a datatable as parameters to a PHP script

I am facing a challenge with my datatable that has two columns, "Name" and "Age". After populating the datatable using Ajax, I create a button for each row. The goal is to send the "Name" and "Age" fields of the clicked row to a PHP script, which will then ...

Utilizing Immutable.js within React's Pure Components

Having some difficulty incorporating React PureComponents with Immutable.js. Take a look at this demonstration: https://codepen.io/SandoCalrissian/pen/QaEmeX The demo showcases 2 components being rendered. The first (NoramlPure) is a regular PureComponen ...

Animating transitions in a Vuetify data table

I am in the process of animating the data on a Vuetify data table. My objective is to make the current data slide out to the right when Next is clicked, and then have the new data slide in from the left. The current result I am getting can be viewed here: ...

In the event that the hash consists of just one string, disregard any additional conditional statements

Currently, I am in the process of updating one of my coding playgrounds and facing some issues. If the user has only the "result" string in the hash like this... testhash.html#d81441bc3488494beef1ff548bbff6c2?result I want to display only the result ( ...

The AngularJS 2 application reports that the this.router object has not been defined

My function to sign up a user and redirect them to the main page is implemented like this: onSubmit(){ this.userService.createUser(this.user).subscribe(function (response) { alert('Registration successful'); localStor ...

Dynamic v-if condition based on data binding

Is it possible to bind a v-if directive to data? I have an array of objects that represent navigation links or buttons, such as login and logout. Each object in this array has a 'v-if' property where the condition is defined as a string. Sample ...

Tips for incorporating the "define" function into your Mocha testing

Starting my journey with JavaScript testing, I made the decision to use Mocha. The specific modules I am looking to test are AMD/RequireJS. However, it appears that Mocha only works with CommonJS modules. Consequently, when trying to run it, I encounter t ...

What is the most effective method for identifying the initial timestamp for each day, week, or month within a collection of timestamps?

I am dealing with a lengthy array of sorted timestamps representing stock price quotes. These timestamps have minimal resolution, meaning that each timestamp is at least 1 minute bigger than the previous one. However, there can be gaps during the day, espe ...

Angular: Verify that all services are fully executed before proceeding to the next step

We have adopted Angular for our project. Our component receives data from an API, which is then processed by Data Services. These services transform the data by combining first and last names, rounding dollar amounts, performing calculations, etc. The fina ...

Utilizing a React component for interactive button functionality

In my React app, I decided to enhance my buttons by incorporating images using SVG. After discovering that I needed a separate component for my SVG files, I came across this helpful resource and created my own <SVGIcon /> component. However, when at ...

What is the best way to keep track of the number of checked checkboxes and add them to a separate div?

I need to select multiple checkboxes from different sections, count them, and then append the same number of sections to another div. ...

How can I show the total sum of input values in a React.js input box?

Is there a way to dynamically display the sum of values entered in front of my label that updates automatically? For example, you can refer to the image linked below for the desired output Output Image I have initialized the state but I'm struggling ...

Executing a js.erb template while submitting a form with AJAX in a Rails application

My form setup looks like this: <div class= "parent-container"> <%= form_with scope: @company, url: companies_path, html: { class: "form-inline", remote: true, "data-type" => :js, id: "new-company-create" }, local: true do |f| %> <d ...

Is it recommended to place the styles created by material-ui for child components after the styles generated for the parent component?

Utilizing material-ui, which utilizes JSS for styling a website. I have a component named Layout that applies margin to all its children (using the all children selector & > * in its style). This functionality works, but I would also like the child ...