在 vue 计算中使用箭头函数不起作用

IT技术 javascript vue.js vuejs2
2021-02-05 20:50:05

我正在学习 Vue 并在计算属性中使用箭头函数时遇到问题。

我的原始代码工作正常(见下面的片段)。

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>

但是,在我更改计算属性中的方法后,颜色不会改变(尽管 turnRed 值仍然成功地在 true 和 false 之间切换)。

这是我的代码:

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

我使用了错误的语法吗?

6个回答

您正面临此错误,因为箭头函数不会绑定this到您为其定义计算属性的 vue 实例。如果您要methods使用箭头函数进行定义,也会发生同样的情况

不要在实例属性或回调上使用箭头函数(例如vm.$watch('a', newVal => this.myMethod()))。由于箭头函数绑定到父上下文,这不会是您期望的 Vue 实例,并且this.myMethod将是未定义的。

你可以在这里阅读它

您可以使用箭头函数并通过解构访问此对象。看我的回答。
2021-03-14 20:50:05
尽管在不需要访问this对象时可以使用箭头函数:计算:{ switchRed: () => ({red: "red"}), ... }
2021-04-06 20:50:05

箭头函数丢失了 Vue 组件上下文。为了您的功能methodscomputedwatch等,使用对象的功能:

computed:{
    switchRed() {
        return {red: this.turnRed}
    },
    switchGreen() {
        return {green: this.turnGreen}
    },
    switchBlue() {
        return {blue: this.turnBlue}
    }
}
我注意到的一件奇怪的事情是,当您使用箭头函数定义计算属性,然后使用 chrome devtools 进行调试时,它仍然看起来好像“this”正在引用 VueJS 组件上下文。我花了很长时间才发现箭头函数导致了我的问题,因为当我在箭头函数中放入“调试器”语句然后检查“this”时,所有组件数据都显示出来了,但是当我尝试使用 console.log()我的组件数据未定义。
2021-03-11 20:50:05
这是最有用的答案,因为它解释了如何解决问题。我会推荐这个答案和公认的答案作为实际的“整体理想”答案。
2021-03-13 20:50:05
我唯一可以在这里添加的是,如果您在这些函数中具有函数,例如回调,那么使用箭头函数将使您的代码更清晰,因为它使用来自封闭上下文的此对象,现在是 vue 实例。
2021-03-23 20:50:05

为什么不做这样更简单的事情呢?

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>

在创建您不使用的计算时=>,您应该只使用switchRed () {...

看一下片段。正常工作。

它适用于所有计算、方法、观察者等。

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>

你可以通过解构你想要的东西来实现这一点:

computed:{
  switchRed: ({ turnRed }) => {red: turnRed},
  switchGreen:  ({ turnGreen }) => {green: turnGreen},
  switchBlue: ({ turnBlue }) => {blue: turnBlue}
}
这是有效的,因为计算属性接收组件实例作为它们的第一个参数。所以这基本上是 switchRed: (this) => {red: this.turnRed}
2021-03-26 20:50:05