Pleinair
Pleinair

Reputation: 449

Vue.js removing objects from array not working

I have a Vue.js project where I'm trying to remove object from items array by clicking the remove button in CheckList.vue file, but I'm getting following error: Property or method "remove" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. Can anyone help?

Example.vue

 <template>
  <div>
    <input type="text" v-model="message" @keyup.enter="add">
    <button @click="add">Add Item</button>
    <CheckList :items="items" all="all" title="All Items"></CheckList>  <!-- v-bind --> 
    <CheckList :items="doneItems" title="Done Items"></CheckList>
    <CheckList :items="notDoneItems" title="Not Done Items"></CheckList>
  
  </div>
</template>

<script>
import CheckList from "./CheckList";
export default {
  name: "Example",
  components: {CheckList},
  data() {
    return {
      message: '',
      items: [
        {name:'Apple', done: true, key: 0},
        {name:'Orange', done: false, key: 1},
        {name:'Grapes', done: true, key: 2},
      ],
      
    }
  },
  methods: {
    add(){
      if(this.message !== '') {
        this.items.push({
          name: this.message,
          done: false,
          key: this.items.length
        });
        this.message = '';
      }
    
    },
    remove(index){
        this.events.splice(index, 1);
    }
    
    
  },
  
  computed: {
    doneItems(){
      return this.items.filter(item => item.done);
    },
    notDoneItems(){
      return this.items.filter(item => !item.done);
    }
  }
}
</script>

<style scoped>

  
  
</style> 

CheckList.vue

<template>
  <div>
    <h3>{{ title }}</h3>

    <ul>
      <li v-for="(item,key) in items" :key="item.key">
        <input type="checkbox" v-model="item.done">
        {{item.name}}
        <button v-if="all" v-on:click="remove(key)" class="button1">remove</button>
      </li>
    </ul>
    
    
  </div>
</template>

<script>
export default {
  name: "CheckList",
  props: ['items', 'title', 'all']
}
</script>

<style scoped>
.button1{
    margin-left:10px;
  }
</style>

Upvotes: 2

Views: 520

Answers (1)

Nikola Pavicevic
Nikola Pavicevic

Reputation: 23480

Try like following snippet:

Vue.component('check-list', {
  template: `
    <div>
      <h3>{{ title }}</h3>
      <ul>
        <li v-for="(item,key) in items" :key="item.key">
          <input type="checkbox" v-model="item.done">
          {{item.name}}
          <button v-if="all" v-on:click="$emit('remove',key)" class="button1">remove</button>
        </li>
      </ul>
    </div>
  `,
  props: ['items', 'title', 'all'],
  methods: {
    remove() {
      $emit('remove', 'key')
    }
  }
})

new Vue({
  el: '#demo',
  data: {
    message: '',
    items: [
      {name:'Apple', done: true, key: 0},
      {name:'Orange', done: false, key: 1},
      {name:'Grapes', done: true, key: 2},
    ],
  },
  computed: {
    doneItems(){
      return this.items.filter(item => item.done);
    },
    notDoneItems(){
      return this.items.filter(item => !item.done);
    }
  },
  methods: {
    add(){
      if(this.message !== '') {
        this.items.push({
          name: this.message,
          done: false,
          key: this.items.length + 1
        });
        this.message = '';
      }
    
    },
    remove(index){
        this.items.splice(index, 1);
    }
    
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
  <div>
    <input type="text" v-model="message" @keyup.enter="add">
    <button @click="add">Add Item</button>
    <check-list :items="items" all="all" title="All Items" @remove="remove" />
  </div>
</div>

Upvotes: 1

Related Questions