Vue.js Adding a class by using computed

Viewed 200

I am a beginner at Vue.js. I would like to add a class, which depends on conditionals. I wanna remove the success class when the answer is greater than 25, but the color doesn't change... could you please give me any advice?

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>Caliculator</title>
   </head>
   <body>
      <div id="app">
         <input type="number" name="num1" v-model.number="num1" /> +
         <input type="number" name="num2" v-model.number="num2" /> +
         <input type="number" name="num3" v-model.number="num3" /> +
         <input type="number" name="num4" v-model.number="num4" /> +
         <input type="number" name="num5" v-model.number="num5" /> =
         <span class="error" :class="classObject">{{ answer }}</span>
      </div>

      <style>
         .success {
            color: green;
         }
      </style>
      <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
      <script>
         var app = new Vue({
            el: "#app",
            data: {
               num1: 0,
               num2: 0,
               num3: 0,
               num4: 0,
               num5: 0,
               classObject: {
                  success: true,
               },
            },
            computed: {
               answer: function () {
                  return (
                     this.num1 + this.num2 + this.num3 + this.num4 + this.num5
                  );
               },
               classObject: function () {
                  if (this.answer > 25) {
                     success: false;
                  }
               },
            },
         });
      </script>
   </body>
</html>
4 Answers

I am not a vue developer

but you can try this:

<span class="error" v-bind:class="classObject">{{ answer }}</span>


 classObject: function () {
    return {
      success: this.answer > 25 ? true : false ,

    }
  }

class-binding is more suitable here:

new Vue({
  el: "#app",
  data: { 
    num1: 0, num2: 0, num3: 0, num4: 0, num5: 0
  },
  computed: {
    answer: function () {
      return (this.num1 + this.num2 + this.num3 + this.num4 + this.num5);
    }
  },
});
.success { color: green; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <input type="number" name="num1" v-model.number="num1" /> +
  <input type="number" name="num2" v-model.number="num2" /> +
  <input type="number" name="num3" v-model.number="num3" /> +
  <input type="number" name="num4" v-model.number="num4" /> +
  <input type="number" name="num5" v-model.number="num5" /> =
  <span class="error" :class="{ 'success': answer <= 25 }">{{ answer }}</span>
</div>

But if you insist on using a computed property:

new Vue({
  el: "#app",
  data: { 
    num1: 0, num2: 0, num3: 0, num4: 0, num5: 0
  },
  computed: {
    answer: function () {
      return (this.num1 + this.num2 + this.num3 + this.num4 + this.num5);
    },
    classObject: function () {
      return { 'success': (this.answer <= 25) };
    },
  },
});
.success { color: green; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <input type="number" name="num1" v-model.number="num1" /> +
  <input type="number" name="num2" v-model.number="num2" /> +
  <input type="number" name="num3" v-model.number="num3" /> +
  <input type="number" name="num4" v-model.number="num4" /> +
  <input type="number" name="num5" v-model.number="num5" /> =
  <span class="error" :class="classObject">{{ answer }}</span>
</div>

This is why because you're trying mutate success that is in Object. Here vue.set should help you. But there is easier solutions. Try something like:

:class="answer > 25 ? '' : 'success'"

The color does not change because classObject is well defineas a computed, but also in the data section. Thus it is never updated!!! Remove it from the data section then it should work.

EDIT: As noticed by @keskinsaf, there is also an error in your computed property which missing a return statement. => Fixed in the code below:

  <script>
     var app = new Vue({
        el: "#app",
        data: {
           num1: 0,
           num2: 0,
           num3: 0,
           num4: 0,
           num5: 0,
           classObject: {     //  remove
              success: true,  //  these
           },                 //  lines
        },
        computed: {
           answer() {
              return this.num1 + this.num2 + this.num3 + this.num4 + this.num5;
           },
           classObject() {
              return { success: this.answer <= 25 }; // add return statement
           },
        },
     });
  </script>

However, I highly recommend you to prefer using class-binding:

:class="{ 'success': answer <= 25 }"
Related