Dr.Kameleon
Dr.Kameleon

Reputation: 22820

Problem when triggering a Vue function to change some component field

Ok, so, be warned that this is a very newbie question since I'm only getting started with Vue.js.

So, I have a label and a button. If the label is not visible, the button should say "Show Label" and when clicked... show the label. When the label is visible, the button should say "Hide Label" and when clicked, hide it.

This (with computed properties) shows/hides the label, but does not change the button caption:

<html>
    <head>
        <link rel="stylesheet" href="index.css">
        <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
    </head>
    <body>

        <div id="app">
            {{ message }}
            This is another thing: <b>{{thing}}</b><br>
            <span :title="title" @click="doSomething">NO TITLE</span>
            <ul v-for="item in items">
                <li>{{item}}</li>
            </ul>
            <button @click="labelVisible=!labelVisible">{{toggleMessage}}</button>
            <label v-if="labelVisible">This is my label</label>
        </div>
    </body>
    <script>
        var app = new Vue({ 
            el: '#app',
            data: {
                message: 'Hello Vue!',
                thing: 'thing',
                title: "This is the title",
                doSomething: ()=>{
                    alert("did something")
                },
                items: ["one", "two", "three"],
                labelVisible: true
            },
            computed: {
                toggleMessage: ()=>{
                    if (this.labelVisible) {
                        return "Hide Label";
                    }
                    else {
                        return "Show Label";
                    }
                }
            }
        });
    </script>
</html>

This one (just with an on:click binding) doesn't do anything:

<html>
    <head>
        <link rel="stylesheet" href="index.css">
        <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
    </head>
    <body>

        <div id="app">
            {{ message }}
            This is another thing: <b>{{thing}}</b><br>
            <span :title="title" @click="doSomething">NO TITLE</span>
            <ul v-for="item in items">
                <li>{{item}}</li>
            </ul>
            <button @click="buttonClicked">{{toggleMessage}}</button>
            <label v-if="labelVisible">This is my label</label>
        </div>
    </body>
    <script>
        var app = new Vue({ 
            el: '#app',
            data: {
                message: 'Hello Vue!',
                thing: 'thing',
                title: "This is the title",
                doSomething: ()=>{
                    alert("did something")
                },
                items: ["one", "two", "three"],
                labelVisible: true,
                toggleMessage: "Hide Label",
                buttonClicked: ()=> {
                    this.labelVisible = !this.labelVisible;
                    if (this.labelVisible) {
                        this.toggleMessage = "Hide Label";
                    }
                    else {
                        this.toggleMessage = "Show Label";
                    }
                }
            }
        });
    </script>
</html>

Preferably, I would like to get both of them working. But I still cannot see what I'm doing wrong. The Vue DevTools report no issue whatsoever...


UPDATE:

In the second case, when printing out the values of labelVisible and toggleMessage, they do change fine. It's just that the change is not reflected in the component.

Upvotes: 0

Views: 50

Answers (1)

Dr.Kameleon
Dr.Kameleon

Reputation: 22820

OK, So, I'm posting myself the answer.

What @AlexBrohshtut spotted was right. Fat-arrow functions were an issue.

However, the most important part is that I hadn't put my function in methods (I had them in data section too). Pff...

So, this works:

<html>
    <head>
        <link rel="stylesheet" href="index.css">
        <script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
    </head>
    <body>

        <div id="app">
            {{ message }}
            This is another thing: <b>{{thing}}</b><br>
            <span :title="title" @click="doSomething">NO TITLE</span>
            <ul v-for="item in items">
                <li>{{item}}</li>
            </ul>
            <button @click="buttonClicked">{{toggleMessage}}</button>
            <label v-if="labelVisible">This is my label</label>
        </div>
    </body>
    <script>
        var app = new Vue({ 
            el: '#app',
            data: {
                message: 'Hello Vue!',
                thing: 'thing',
                title: "This is the title",
                doSomething: ()=>{
                    alert("did something")
                },
                items: ["one", "two", "three"],
                labelVisible: true,
                toggleMessage: "Hide Label",

            },
            methods: {
                buttonClicked: function() {
                    console.log("button");
                    this.labelVisible = !this.labelVisible;
                    console.log(this.labelVisible);
                    if (this.labelVisible) {
                        this.toggleMessage = "Hide Label";
                    }
                    else {
                        this.toggleMessage = "Show Label";
                    }
                    console.log(this.toggleMessage);
                }
            }
        });
    </script>
</html>

Upvotes: 1

Related Questions