Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The method in Vue runs twice on click

Why does the method set runs twice? You can see the console when you click the star. If I remove @click="set(rating)" nothing happens so not like it is again called elsewhere.

http://jsfiddle.net/q22tqoLu/

HTML

<div id="star-app" v-cloak>
            <star-rating value="0"></star-rating>
        </div>

        <template id="template-star-rating">
            <div class="star-rating">
                <label
                class="star-rating__star"
                v-for="rating in ratings"
                :class="{'is-selected': ((value >= rating) && value != null), 'is-disabled': disabled}"
                @mouseover="star_over(rating)"
                @mouseout="star_out"
                @click="set(rating)">
                <input
                class="star-rating star-rating__checkbox"
                type="radio"
                :name="name"
                :disabled="disabled"
                :id="id"
                :required="required"
                v-model="value">
                ★
            </label>
        </div>
    </template>

JS

  'use strict';

    Vue.component('star-rating', {
        template: '#template-star-rating',
        data: function data() {
            return {
                value: null,
                temp_value: null,
                ratings: [1, 2, 3, 4, 5]
            };
        },
        props: {
            'name': String,
            'value': null,
            'id': String,
            'disabled': Boolean,
            'required': Boolean
        },
        methods: {
            star_over: function star_over(index) {
                if (this.disabled) {
                    return;
                }

                this.temp_value = this.value;
                this.value = index;
            },
            star_out: function star_out() {
                if (this.disabled) {
                    return;
                }

                this.value = this.temp_value;
            },
            set: function set(value) {
                if (this.disabled) {
                    return;
                }

          // This runs twice
          console.log(value);

                this.temp_value = value;
                this.value = value;
            }
        }
    });

    new Vue({
        el: '#star-app'
    });

The code is based on older version from someone, here it also doubles https://codepen.io/sktwentysix/pen/oZwXjN

like image 481
Ivan Topić Avatar asked Aug 03 '17 10:08

Ivan Topić


People also ask

How do I stop Vue clicking?

We can prevent the click event from propagating to the parent when clicking a button inside an element with Vue. js with the self modifier. We add the self modifier to the @click directive on the outer div so that the click event will be confined to the parent div.

Does Vue use two-way binding?

Two-way binding is a powerful feature that, if used properly, can significantly speed up your development process. It reduces the complexity of keeping user input consistent with the application data model. In Vue, two-way binding is accomplished using the v-model directive.

How do I stop popping up when I click outside Vue?

Close Dialog while Click on Outside of Dialog in Vue Dialog component. By default, dialog can be closed by pressing Esc key and clicking the close icon on the right of dialog header.


3 Answers

If you move @click="set(rating)" to <input/> instead of <label/>, it will run once.

like image 156
Vad Avatar answered Oct 25 '22 11:10

Vad


@click.stop="clickfunction($event)"

This will stop next calls and will call function only once.

like image 32
Rupesh Terase Avatar answered Oct 25 '22 11:10

Rupesh Terase


It is a default browser behavior. Clicking on the <label> will trigger 2 clicks, one for <label> and one for <input>.

Way to avoid that is to add @click.prevent to your <label> tag.

like image 29
Jakub A Suplicki Avatar answered Oct 25 '22 12:10

Jakub A Suplicki