0

So I want to apply the class .testcolor to the div when testvalue is true and apply nothing when it's false.

When i add the getClass method to :class it doesn't even get called but it gets called when called from {{ getClass }}. I tried clearing the cache and even rewrote the entire code and it still doesnt work! Here is the full code:

<!DOCTYPE html>
<html>
    <head>
        <title>Vue Test</title>
        <style>
            .testcolor {
                color: red !important;
            }
        </style>
    </head>
    <body>
        <div id="test" :class="getClass">
            <h1>Test stuff</h1>
            <h2>{{ testvalue }}</h2>
        </div>
        <script type="module">
            import { createApp } from "https://unpkg.com/[email protected]/dist/vue.esm-browser.js";

            createApp({
                data() {
                    return {
                        testvalue: true,
                    };
                },
                methods: {
                    getClass() {
                        console.log("Method 'getClass' called");
                        return this.testvalue ? "testcolor" : "";
                    },
                },
            }).mount("#test");
        </script>
    </body>
</html>

I figured something out that if I mount the Vue instance on the div element and add the :class="testClass" (from the answer) to the h2 it works! But when I mount it on the h2 element now it doesn't work!

1 Answer 1

1

EDIT based on your comment @martin0300

Firstly, you need to wrap the division in another division whose id must be test. Vue does not consider the container element (div with id test) as part of the app and does not process any directives. Left a references below that mentions this.

https://vuejs.org/guide/essentials/application.html#mounting-the-app

So please change your markup to something like this for applying the value from getClass method...

<div id="test">
    <div :class="getClass()">
        <h1>Test stuff</h1>
        <h2>{{ testvalue }}</h2>
    </div>
</div>

...or this way for using the computed property approach (explained below.)

<div id="test">
    <div :class="testClass">
        <h1>Test stuff</h1>
        <h2>{{ testvalue }}</h2>
    </div>
</div>

--

Original message:

getClass when defined as a method needs to be called, and the returned value ("testcolor") is set as the value of :class. Note the function call getClass() in place of the getClass you used.

<div id="test" :class="getClass()">
    <h1>Test stuff</h1>
    <h2>{{ testvalue }}</h2>
</div>

That said, this is not the preferred way to apply classes conditionally. We prefer a computed property over of a method. A method is invoked on every render, whereas a computed property is recomputed only when the underlying reactive data it depends on changes (in this case the computed property testClass depends on the reactive property testvalue.

The idiomatic Vue code in your case would be the following. Note that computed properties are not invoked like functions since they are internally implemented using accessor methods / using a JS Proxy (:class="testClass" and NOT :class="testClass()"). I believe this difference between the way methods and computed properties are used is the cause of your confusion.

<div id="test" :class="testClass">
    <h1>Test stuff</h1>
    <h2>{{ testvalue }}</h2>
</div>
<script type="module">
    import { createApp } from "https://unpkg.com/[email protected]/dist/vue.esm-browser.js";

    createApp({
        data() {
            return {
                testvalue: true,
            };
        },
        computed: {
            testClass() {
                console.log("Recomputed testClass");
                return this.testvalue ? "testcolor" : "";
            },
        },
    }).mount("#test");
</script>

Sign up to request clarification or add additional context in comments.

3 Comments

I tried your code but it still didn't work and the log message didn't appear in the console! The only thing in the console is a warning about using the development version of Vue.
I edited the original question and added new information on the bottom. I think it may help.
I have modified the answer based on your feedback @martin0300

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.