Efficiently removing a duplicated component in Vue: A step-by-step guide

I am trying to find a way to target and remove a component that I duplicated using the v-for directive in my multiple stopwatch application. Currently, I can only delete the last duplicated component, but I want the ability to remove any targeted component. Below is the code for my "Counter" component:

<template>
  <div class="chrono">
    <h2><input type="text" :placeholder="'Chrono' + number" /></h2>
    <div class="timer">
      <input type="number" v-model.number="hours">:
      <input type="number" v-model.number="minutes">:
      <input type="number" v-model.number="seconds">
    </div>
    <div class="controls">
      <button @click="handleCounter">{{ startStop }}</button>
      <button @click="resetCounter">reset</button>
    </div>
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: "Counter",
  data() {
    return {
      hours: 0,
      minutes: 0,
      seconds: 0,
      startStop: "start",
      interval: "",
    };
  },
props:["number"],
  methods: {
    handleCounter() {
      if (this.startStop === "start") {
        this.interval = setInterval(
          function () {
            this.seconds++;
            if (this.seconds + 1 > 60) {
              this.minutes++;
              this.seconds = 0;
            }
            if (this.minutes + 1 > 60) {
              this.hours++;
              this.seconds = 0;
              this.minutes = 0;
            }
          }.bind(this),
          1000
        );
        this.startStop = "stop";
      } else if (this.startStop === "stop") {
        clearInterval(this.interval);
        this.startStop = "start";
      }
    },
    resetCounter() {
      this.seconds = 0;
      this.minutes = 0;
      this.hours = 0;
    },
  },
};
</script>

<style scoped lang="scss">
.chrono {
  border: 1px solid black;
  margin: auto;
  border-radius: 5px;
}
.timer{
display: flex;
flex-flow: row;
justify-content: center;

}
.timer input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
  
  -webkit-appearance: none;
  margin: 0;
}
.timer input{
  width: 25px;
  border: none;
  text-align: center;
}

</style>

Furthermore, here is the code for the App.vue file where I aim to duplicate or delete instances of my Counter component:

<template>
  <section>
    <button @click="addCounter">+</button>
    <div class="listOfCounter" >
      <Counter v-for="index in count" :key="index" :number="index">
        <button @click="removeCounter">-</button>
      </Counter>
    </div>
  </section>
</template>

<script>
import Counter from "./components/Counter.vue";

export default {
  name: "App",
  components: {Counter},
  data() {
    return { count: 1,
    index:[]
    };
  },
  methods: {
    addCounter() {

      this.count++;
    },
    removeCounter() {
      this.count--;
    },
  },
};
</script>

<style lang="scss">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Answer №1

If you convert the variable count to an array, you can then use push/filter methods to add or remove counters:

Vue.component('Counter', {
  template: `
    <div class="chrono">
    <h2><input type="text" :placeholder="'Chrono' + number" /></h2>
    <div class="timer">
      <input type="number" v-model.number="hours">:
      <input type="number" v-model.number="minutes">:
      <input type="number" v-model.number="seconds">
    </div>
    <div class="controls">
      <button @click="handleCounter">{{ startStop }}</button>
      <button @click="resetCounter">reset</button>
    </div>
    <slot></slot>
  </div>
  `,
  data() {
    return {
      hours: 0,
      minutes: 0,
      seconds: 0,
      startStop: "start",
      interval: "",
    };
  },
  props:["number"],
  methods: {
    handleCounter() {
      if (this.startStop === "start") {
        this.interval = setInterval(
          function () {
            this.seconds++;
            if (this.seconds + 1 > 60) {
              this.minutes++;
              this.seconds = 0;
            }
            if (this.minutes + 1 > 60) {
              this.hours++;
              this.seconds = 0;
              this.minutes = 0;
            }
          }.bind(this),
          1000
        );
        this.startStop = "stop";
      } else if (this.startStop === "stop") {
        clearInterval(this.interval);
        this.startStop = "start";
      }
    },
    resetCounter() {
      this.seconds = 0;
      this.minutes = 0;
      this.hours = 0;
    },
  },
})

new Vue({
  el: '#demo',
  data() {
    return { 
      count: [0],
      index: []
    };
  },
  methods: {
    addCounter() {
      this.count.push(Math.max(...this.count)+1);
    },
    removeCounter(index) {
    console.log(this.count)
      this.count = this.count.filter(i => i !== index);
    },
  },
})
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
.chrono {
  border: 1px solid black;
  margin: auto;
  border-radius: 5px;
}
.timer{
display: flex;
flex-flow: row;
justify-content: center;

}
.timer input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
  
  -webkit-appearance: none;
  margin: 0;
}
.timer input{
  width: 25px;
  border: none;
  text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
  <section>
    <button @click="addCounter">+</button>
    <div class="listOfCounter" >
      <Counter v-for="index in count" :key="index" :number="index">
        <button @click="removeCounter(index)">-</button>
      </Counter>
    </div>
  </section>
</div>

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

Error: Unable to access the 'classList' property of null in HTMLSpanElement.expand function

Encountering a minor issue with my javascript code. Following a tutorial for a seemingly simple task: link What I did: Adapted the HTML from the tutorial to fit my desired visual outcome while maintaining correct class and id attributes. Utilized identic ...

Ways to merge two select options in a form

I'm attempting to merge the selections from two dropdown menus in a form into one variable before submitting the form. Here is an overview of my code: In new.html.erb (for RoR): <%= form_for :character, url: characters_path, method: :post do |f| ...

JS, Async (library), Express. Issue with response() function not functioning properly within an async context

After completing some asynchronous operations using Async.waterfall([], cb), I attempted to call res(). Unfortunately, it appears that the req/res objects are not accessible in that scope. Instead, I have to call them from my callback function cb. functio ...

The beautiful synergy between Vuetify's v-input component and overflow animation

I am having trouble implementing an overflow animation on vuetify's v-text-field component. Despite my efforts, I can't seem to make it work as intended: <script setup> const text = 'very long long long long long text' </scri ...

The unusual behavior of the :to attribute on @click in Vue

I have a specific element: Hashtag.vue: <template> <router-link :to="getTo" custom v-slot="{ navigate }"> <div role="link" @click="navigate"> {{text}}</div> </rout ...

Ways to adjust the size or customize the appearance of a particular text in an option

I needed to adjust the font size of specific text within an option tag in my code snippet below. <select> <?php foreach($dataholder as $key=>$value): ?> <option value='<?php echo $value; ?>' ><?php echo ...

Meta tag information from Next.js not displaying properly on social media posts

After implementing meta tags using Next.js's built-in Head component, I encountered an issue where the meta tag details were not showing when sharing my link on Facebook. Below is the code snippet I used: I included the following meta tags in my inde ...

Error encountered while submitting ajax request to server

When I click a button, a function is triggered with the argument insertSongPlay(newSong.songID);. After logging the value of newSong.songID, which is 90 as desired, an ajax call is made: function insertSongPlay(songID) { $.ajax ({ type: " ...

Guide on creating an AJAX request for a POST method

I am new to working with AJAX, and I have been trying to use it for a POST function similar to the curl command below: curl -X POST -H 'Content-type:application/json' --data-binary '{ "replace-field":{ "name":"sell-by", "type":"date", " ...

"Learn the trick to replace the Ctrl + N shortcut in Firefox and initiate an AJAX request

Note: The answer provided by Juan Mendes has been selected as the best answer for my situation due to its usefulness. AxGryndr also offered valuable information, so I recommend reading both answers as they are beneficial in different scenarios. Thank you t ...

Unable to open javascript dialog box

One issue I encountered involves a jqGrid where users have to click a button in order to apply any row edits. This button is supposed to trigger a dialog box, which will then initiate an ajax call based on the selected option. The problem lies in the fact ...

Error in fullCalendar where events are appearing on incorrect days in the month view of the current month

https://i.sstatic.net/v8Faj.png My fullcalendar plug-in is causing some trouble. I'm trying to show events in the monthview of the calendar, but when I'm in the current month, events on the same day of the week are not displaying correctly. They ...

Accessing the admin panel of a headless CMS using Nuxt.js and WordPress

I'm facing an issue. I recently set up Wordpress and enabled the REST API. Following that, I created a Nuxt.js app. The app runs on localhost:3000 (using "npm run dev" command) I configured XAMPP so that the document root of the server points to the ...

I did not anticipate the React setState function to behave in the manner it did

While working on form validation for my page, I came across a tutorial showcasing a validation method that seems to be functioning correctly. However, there is one aspect that I am struggling to grasp. The tutorial suggests declaring a variable before the ...

Dynamic visual content (map)

I'm currently working on creating an interactive image for my website where clicking on points A, B, C, ... N will reveal bubbles with images and text inside them. Would anyone be able to provide guidance on how to achieve this? Or direct me to resou ...

What could be causing the issue of a Javascript array not filling inside a loop, even though it functions properly

I have a JSON dataset and I'm trying to extract the information of individuals who haven't paid their dues. Initially, when running the code with the if statement commented out, it works perfectly fine - giving the expected output in both the con ...

Encountered an error trying to access the length property of an undefined variable while passing props

I need help with my shopping app project. I am trying to create a feature where if the cart is empty, it should display a message saying "shopping cart is empty." However, when I try to implement this, I keep getting a type error that says "Cannot read p ...

Is the express.json() middleware for parsing JSON request body designed to handle synchronous calls?

According to Express.js's documentation, it is recommended to avoid using synchronous functions as much as possible. This is because in high-traffic websites, the accumulation of synchronous calls can negatively impact the performance of the applicati ...

Accessing the parent element from a clicked child element within a nested v-for loop

Is there a way to access the parent element of a clicked child element using the @click method? For example: <div v-for="(item, index) in bubles"> {{item.name}} <div v-for="subItem in item.bubles"> <a @click="openModal(subItem)"&g ...

Error encountered while using the Fetch API: SyntaxError - the JSON data contains an unexpected character at the beginning

I've been troubleshooting a contact form and there seems to be an error causing it to malfunction. It's strange because when I switch from Fetch to XMLHttpRequest, the code works fine. With Fetch, if I don't request a response, no errors ar ...