Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Computed Properties inside Methods in vueJs

I'm trying to create a shuffle function in vue.js. So, for this i created a computed properties and then i call a method. but it doesn't working. I've created two more function 'add' and 'remove' these two working fine except 'shuffle'.

Throwing an error: Uncaught TypeError: this.moveIndex is not a function

var app = new Vue({
  el: '#root',
  data: {
    tasks: [1,8,9],
    nextNum: 10
  },
  computed: {
    moveIndex: function(array){
      var currentIndex = array.length, randomIndex, tempVal;
      for(var i = currentIndex - 1; i > 0; i--){
        randomIndex = Math.floor(Math.random() * currentIndex);
        tempVal = array[i];
        array[i] = array[randomIndex];
        array[randomIndex] = tempVal;
      }
      return array;
    }
  },
  methods: {
    randIndex: function(){
      return Math.floor(Math.random() * this.tasks.length);
    },
    add: function(){
      this.tasks.splice(this.randIndex(),0,this.nextNum++)
    },
    remove: function(){
      this.tasks.splice(this.randIndex(),1)
    },
    shuffle: function(){
      var arr = this.tasks;
      arr = this.moveIndex(arr)
    }
  }
});
.bar-enter-active, .bar-leave-active{
  transition: all 1s;
}
.bar-enter, .bar-leave-to{
  opacity: 0;
  transform: translateY(30px)
}
.bar-move{
  transition: transform 1s 
}
.numbers{
  margin-right: 10px;
  display: inline-block
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>

	<div id="root">
		<button @click="add">Add</button>
		<button @click="remove">Remove</button>
		<button @click="shuffle">Shuffle</button>
		<transition-group name="bar" tag="div">
			<span v-for="task in tasks" :key="task" class="numbers">{{task}}</span>
		</transition-group>
	</div>
like image 290
kvinbabbar Avatar asked Jul 08 '18 08:07

kvinbabbar


People also ask

Can we call a method in computed property?

Computed Caching vs MethodsInstead of a computed property, we can define the same function as a method. For the end result, the two approaches are indeed exactly the same. However, the difference is that computed properties are cached based on their reactive dependencies.

What is the difference between a computed property and methods in Vue JS?

In my understanding (please correct me if I'm wrong), computed is the same as methods property, only it will be re-executed if data that are used within the property are changed. While methods property will be re-executed for any data changes within the page.

Can I use computed in V model?

We can use this method to combine computed properties and the v-model in order to write the most robust code on Vue. js.

Is computed property reactive in Vue?

The Basics of Vue Reactivity Simply put, a computed property's dependencies are the reactive values that help the property that determine the value that is returned. If none of these change, then, again, the cached value will be returned. If no reactive dependency is changed, a computed property is not recalculated.


1 Answers

Computed properties are just getter functions that return a value and are dependent on other reactive properties.

1. Your computed property moveIndex is just modifying an array data property i.e this.tasks. So just use a method instead.

2. You are trying to directly modify an item of the this.tasks array using index. Vue cannot detect such array modifications.

So use this.$set() or Array.prototype.splice() instead.

Here are the changes:

var app = new Vue({
  el: "#root",
  data: {
    tasks: [1, 8, 9],
    nextNum: 10
  },
  methods: {
    randIndex: function() {
      return Math.floor(Math.random() * this.tasks.length);
    },
    add: function() {
      this.tasks.splice(this.randIndex(), 0, this.nextNum++);
    },
    remove: function() {
      this.tasks.splice(this.randIndex(), 1);
    },
    shuffle: function() {
      var array = this.tasks;
      var currentIndex = this.tasks.length;
      var randomIndex;
      var tempVal;

      for (var i = currentIndex - 1; i > 0; i--) {
        randomIndex = Math.floor(Math.random() * currentIndex);
        tempVal = array[i];
        this.$set(array, i, array[randomIndex]);
        this.$set(array, randomIndex, tempVal);
      }
    }
    
  }
});

Here is a working fiddle

like image 57
Vamsi Krishna Avatar answered Nov 15 '22 07:11

Vamsi Krishna