0

I am having an issue changing the color of the button using Vue class binding. Its throwing an Uncaught (in promise) TypeError: $options.isActiveClass is not a function. Can anyone help me please?

Here is my code

<template>
    <div class="step-wrap">
            <button :class="isActiveClass('her')" @click="getButtonActive('her'); isActiveBtn='her' ">For Her</button>
            <button :class="isActiveClass('him')" @click="getButtonActive('him'); isActiveBtn='him' ">For Him</button>
            <button :class="isActiveClass('kids')" @click="getButtonActive('kids'); isActiveBtn='kids' ">For Kids &amp; Teens</button>
        </div>
    </template>

Here is My Script code

 <script>
    export default {
        data() {
                return {
                    isActiveBtn:null,
                    activeClass:'disabled'
                }
            },
            computed:{
                isActiveClass(value)
                {
                    if(value === this.isActiveBtn)
                    {
                        return 'active';
                    }
                    else {
                        return 'disable'
                    }
                }
        
            }
    
    }
    
    </script>
user3718511
  • 317
  • 1
  • 3
  • 15
  • Unfortunately, `computed` is not the right place to put this method -- Try `methods`. However, the class binding won't work that way either. Please go through the essentials again on [class and style bindings](https://v3.vuejs.org/guide/class-and-style.html#class-and-style-bindings). Check out the object or array syntax. – Yom T. Oct 19 '21 at 12:29
  • @YomT. Thanks for your response. So how can I apply class binding with the same method of more than one button? – user3718511 Oct 19 '21 at 12:34
  • Did you look into the [object syntax](https://v3.vuejs.org/guide/class-and-style.html#object-syntax)? The key concept is to toggle the individual "active" states on the button clicks only, and the class binding will be taken care of for you. In other words, I'd suggest renaming your `getButtonActive` to something like `toggleButtonActive` and... you get the idea. – Yom T. Oct 19 '21 at 13:00

2 Answers2

1

Untested, but I would try something like this:

<script>
    export default {
        data() {
                return {
                    isActiveBtn:null,
                    activeClass:'disabled'
                }
            },
            methods:{
                isActiveClass(value) {
                    return {
                        active: value === this.isActiveBtn,
                        disable: value !== this.isActiveBtn
                    }
                }
        
            }
    
    }
</script>

EDIT:
Methods are not reactive, the above only works because it re-renders the template and thus is calling the method again. A better way would be to remove the method altogether and just use the template like this:

<template>
    <div class="step-wrap">
        <button :class="{active: isActiveBtn === 'her', disable: isActiveBtn !== 'her'}" @click="isActiveBtn='her'">For Her</button>
        <button :class="{active: isActiveBtn === 'him', disable: isActiveBtn !== 'him'}" @click="isActiveBtn='him'">For Him</button>
        <button :class="{active: isActiveBtn === 'kids', disable: isActiveBtn !== 'kids'}" @click="isActiveBtn='kids'">For Kids &amp; Teens</button>
    </div>
</template>
Thomas
  • 6,325
  • 4
  • 30
  • 65
  • 1
    Looking at this again, I don't think this is the best way to go. Also have a look at this post here: https://stackoverflow.com/questions/59636004/are-methods-in-vue-reactive So it only works, because it re-renders the template and calls the method again. – Thomas Oct 19 '21 at 14:01
1
computed:{
            isActiveClass() {
                return (value) => {
                    if(value === this.isActiveBtn)
                    {
                        return 'active';
                    }
                    else {
                        return 'disable'
                    }
                }
        
            }
}
jimbo0378
  • 11
  • 3