Choose one distinctive icon from a multitude - vue.js

I'm feeling really confused at the moment. I have a list of items, each with a heart-shaped "like" button. When I click on the icon, I want the color to change. However, the issue is that all the hearts change color instead of just the one I clicked on. Should I include an argument in the markAsFavorite method, such as index or book?


 <template>
    <v-flex v-for="(book, index) in allBooks">
     <div>Title: {{ book.title }}</div>
     <i @click="markAsFavorite(index)" :class="{isActive: isActive(index)}" class="fas fa-heart"></i>
 </template
 <script>
   name: 'Books',
   data () {
      return {
        allBooks: [
           { title: "one" },
           { title: "two" },
           { title: "three" },
           { title: "four" },
         ],
        activeHeartIndex: -1,
     }
   },
  methods: {       
    markAsFavorite(index) {
        this.activeHeartIndex = index;
    },
    isActive(index) {
        return this.activeHeartIndex === index;
    }
   }
 </script>

Answer №1

Each and every item must possess the property isMark as shown below:

UPDATE: You have the option to combine properties with your original data once it has been retrieved:

const myData = [
  { title: "one"},
  { title: "two" },
  { title: "three" },
  { title: "four" },
]

new Vue({
  el: '#app',

  data() {
    return {
      isLoading: true,
      allBooks: []
    }
  },
  
  created() {
    this.fetchAPI()
  },
  
  methods: {
    fetchAPI() {
      setTimeout(() => {
        this.allBooks = myData.map(item => ({...item, isMark: false }))
        this.isLoading = false
      }, 2000)
    },
    
    markAsFavorite(book) {
      book.isMark = !book.isMark
    }
  }
})
.my-icon {  
  cursor: pointer;
  margin-left: 4px;
}

.isActive {
  color: red;
}

.flex {
  display: flex;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/js/all.min.js"></script>

<div id="app">
  <span v-if="isLoading">
    loading
    <i class="fas fa-spinner fa-spin"></i>
  </span>
  
  <template v-else>
    <div class="flex" v-for="(book, index) in allBooks" :key="index">
      <div>Title: {{ book.title }}</div>
      <span
        :class="[
          { isActive: book.isMark }, 
          'my-icon'
        ]"
        @click="markAsFavorite(book)"
      >
        <i class="fas fa-heart"></i>
      </span>
    </div>
  </template>
</div>

Answer №2

To ensure better organization, I recommend creating a separate component for each individual book. This way, each book can manage its own isMark status.

BookComponent.vue

<template>
  <div>
    <div>Title: {{ book.title }}</div>
    <i @click="markAsFavorite" :class="{isActive: isMark}" class="fas fa-heart"></i>
  </div>
</template>

<script>
export default {
  name: 'Book',
  props: { book: Object },
  data() {
    return {
      isMark: false
    };
  },
  methods: {
    markAsFavorite() {
      this.isMark = !this.isMark;
      this.$emit(this.isMark ? 'marked' : 'unmarked', this.book);
    }
  }
}
</script>

Then, in the main Books component:

<template>
  <v-flex v-for="(book, index) in allBooks" :key="index">
    <Book :book="book" @marked="handleMarked" @unmarked="handleUnmarked" />
  </v-flex>
</template>

<script>
import Book from './BookComponent.vue';

export default {
  name: 'Books',
  components: { Book },
  // other necessary code goes here
}
</script>

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

Looking for answers to a question about Handlebars in Node.js? Click on the following link to explore more

After successfully parsing my Shopify product items into a MongoDB database using a model, I am attempting to display them to the user using the express-handlebars package. However, I've encountered a small issue. I'm utilizing <td><a ...

Are you having trouble grasping JavaScript concepts?

Can Javascript replicate Smalltalk's doesNotUnderstand or Ruby's method_missing functionality? ...

include a button next to the input field

As you reduce the browser window size, you may notice a different layout designed specifically for iPhone. One question that arises is how to add a button next to the search text box dynamically using JavaScript. The issue at hand is that the text box is b ...

Error: Unable to register both views with identical name RNDateTimePicker due to Invariant Violation

Encountering an issue while attempting to import: import DropDownPicker from 'react-native-dropdown-picker'; import DateTimePicker from '@react-native-community/datetimepicker'; <DropDownPicker zIndex={5000} ...

How can you refresh a functional component using a class method when the props are updated?

I've created a validator class for <input> elements with private variables error, showMessage, and methods validate and isOk. The goal is to be able to call the isOk function from anywhere. To achieve this, I designed a custom functional compone ...

the slider HTML control is missing a value

Exploring the Range Input Type in HTML When adjusting the value on a slider (Range input type), that value is displayed in a textbox. However, making the same adjustment in the textbox does not update the slider's value. Below is the code snippet: & ...

Issue with Flowtype not properly refreshing when maximizing or minimizing

There is a strange behavior with my Flowtype plugin. When I load the page without maximizing the screen, the font size remains the same even after maximizing the screen. However, if I then restore the window to its original size, the font size adjusts as ...

Cart cannot function as a constructor

I'm currently learning express.js and trying to implement a shopping cart/session functionality into my project. Below is the code I have written so far, with a question at the end. Here is my cart.js: // Ensure that the file is required correctly b ...

Guide to enclosing selected text within a span tag and positioning a div in relation to it using JavaScript

My main objective is to enable the user to: highlight text within a paragraph enclose the highlighted text in a span element add an action button or div at the end of the selected text for further interaction Here's the code I've worked on so ...

Is there a way for me to determine the size of this JSON structure?

Can anyone help me figure out the length of this JSON object? I need to know how many data are in it. var ddData = [{ "01":"United States", "02":"United Kingdom", "03":"Aruba", "04":"United Kingdom", ...

Ways to activate a watcher even when it is assigned to the same newVal

Currently, I am utilizing the vue3 framework with the options api You can refer to the demonstration provided in the following stackbiltz link here In my setup, there is a child-component that features a button. Upon clicking this button, the refresh met ...

What does {``} denote in react-native programming?

During my participation in a collaborative project, I noticed that there is a significant amount of {' '} being used. For instance: <Text> {' '} {constant.Messages.PointText.hey} {this._user.first_name || this._user ...

Next.js allows for dynamic page routing using the `useState` hook to redirect users

In my Next.js project, I am using the useState hook to render different components based on the button a user clicks. The main page, called account.js in the application, contains the following code: // Importing react and getting components import React f ...

Updating an object's matrix in THREE.js after adjusting its position using Raycaster

I'm encountering an issue with FPS camera controls in a three.js scene. My approach involves using a Raycaster to determine the camera group's position by intersecting it with the scene along the Y axis (a makeshift gravity setup) and then applyi ...

Comparing JSON and JavaScript object arrays: Exploring the differences in outcomes and strategies for achieving desired results

Although it's not valid JSON, I've found that by declaring this as a variable directly in my code, I can treat it like an object. <script> // this will result in object var mydata = { users: [{ person: { ...

Transferring and bringing in components in React without ES6

I'm currently working on a react project and I want to export my ShoppingList class. However, I prefer not to use ES6 as I find it confusing. Here is the code for the ShoppingList class: class ShoppingList extends React.Component { render() { ...

Creating code to ensure a div element is displayed only after a specific duration has elapsed

Can anyone help me with coding to make a div appear on a website after a specific amount of time? Here's an example of what I'm trying to achieve: <div class="container"> <div class="secretpopout"> This is the hidden div that should ...

Utilizing Angular JS to ensure services are universally accessible across controllers and views

Imagine we have a service like this: myApp.factory('FooService', function () { ... Now, from a controller, the code would look something like this: myApp.controller('FooCtrl', ['$scope', 'FooService', function ($s ...

Vue router is unable to render or mount the component at the root path

I am currently working on a webpage using vue, vue-router, and laravel. I have encountered an issue where the Home component is not being rendered in the router-view when I access localhost/myproject/public_html/. However, if I click on the router link to ...

Retrieve a result from this promise

I have encountered a problem that my classmates at school cannot solve. I have a piece of code that is working fine and sending the table of objects potentials to the client side. However, I now realize that I also need another object called userData. I ...