Use arrow function in vue computed does not work

2019-01-03 18:25发布

I am learning Vue and facing a problem while using arrow function in computed property.

My original code works fine (See snippet below).

new Vue({
  el: '#app',
  data: {
    turnRed: false,
    turnGreen: false,
    turnBlue: false
  },
  computed:{
  	switchRed: function () {
    	return {red: this.turnRed}
    },
    switchGreen: function () {
    	return {green: this.turnGreen}
    },
    switchBlue: function () {
    	return {blue: this.turnBlue}
    }
  }
});
.demo{
  width: 100px;
  height: 100px;
  background-color: gray;
  display: inline-block;
  margin: 10px;
}
.red{
  background-color: red;
}
.green{
  background-color: green;
}
.blue{
  background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.4/vue.js"></script>
<div id="app">
  <div class="demo" @click="turnRed = !turnRed" :class="switchRed"></div>
  <div class="demo" @click="turnGreen = !turnGreen" :class="switchGreen"></div>
  <div class="demo" @click="turnBlue = !turnBlue" :class="switchBlue"></div>
</div>

However, after I change methods in computed property, the color will not change (though the turnRed value still switch between true and false successfully).

This is my code:

computed:{
    switchRed: () => {
        return {red: this.turnRed}
    },
    switchGreen: () => {
        return {green: this.turnGreen}
    },
    switchBlue: () => {
        return {blue: this.turnBlue}
    }
}

Do I use the wrong syntax ?

4条回答
Lonely孤独者°
2楼-- · 2019-01-03 18:38

You are facing this error because an arrow function wouldn't bind this to the vue instance for which you are defining the computed property. The same would happen if you were to define methods using an arrow function.

Don’t use arrow functions on an instance property or callback (e.g. vm.$watch('a', newVal => this.myMethod())). As arrow functions are bound to the parent context, this will not be the Vue instance as you’d expect and this.myMethod will be undefined.

You can read about it here.

查看更多
做自己的国王
3楼-- · 2019-01-03 18:44

When creating computed you do not use => , you should just use switchRed () {...

Take a look at snippet. Works as it should.

It applies to all computed,method, watchers etc.

new Vue({
  el: '#app',
  data: {
    turnRed: false,
    turnGreen: false,
    turnBlue: false
  },
  computed:{
  	switchRed () {
    	return {red: this.turnRed}
    },
    switchGreen () {
    	return {green: this.turnGreen}
    },
    switchBlue () {
    	return {blue: this.turnBlue}
    }
  }
});
.demo{
  width: 100px;
  height: 100px;
  background-color: gray;
  display: inline-block;
  margin: 10px;
}
.red{
  background-color: red;
}
.green{
  background-color: green;
}
.blue{
  background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.4/vue.js"></script>
<div id="app">
  <div class="demo" @click="turnRed = !turnRed" :class="switchRed"></div>
  <div class="demo" @click="turnGreen = !turnGreen" :class="switchGreen"></div>
  <div class="demo" @click="turnBlue = !turnBlue" :class="switchBlue"></div>
</div>

查看更多
\"骚年 ilove
4楼-- · 2019-01-03 18:44

And why not something simpler like this?

new Vue({
  el: '#app',
  data: {
    turnRed: false,
    turnGreen: false,
    turnBlue: false
  },
  methods:{
  	toggle (color) {
    	this[`turn${color}`] = !this[`turn${color}`];
    }
  }
});
.demo{
  width: 100px;
  height: 100px;
  background-color: gray;
  display: inline-block;
  margin: 10px;
}
.red{
  background-color: red;
}
.green{
  background-color: green;
}
.blue{
  background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.4/vue.js"></script>
<div id="app">
  <div class="demo" @click="toggle('Red')" :class="{red:turnRed}"></div>
  <div class="demo" @click="toggle('Green')" :class="{green: turnGreen}"></div>
  <div class="demo" @click="toggle('Blue')" :class="{blue: turnBlue}"></div>
</div>

查看更多
狗以群分
5楼-- · 2019-01-03 18:54

The arrow funtion lost the VueJS component context. For your functions in methods, computed, watch, ... use the Object functions :

computed:{
    switchRed() {
        return {red: this.turnRed}
    },
    switchGreen() {
        return {green: this.turnGreen}
    },
    switchBlue() {
        return {blue: this.turnBlue}
    }
}
查看更多
登录 后发表回答