我目前正在学习Vue,并且遇到了一个问题,希望有人可以帮助我。

在使用v-on:click指令调用方法时,如果该方法还用于其他地方,则将调用所有其他实例方法。

HTML:

<div id="exercise">
    <div><button class="test" v-on:click="newCheck()">New Challenge</button>
        <p >Success check is: {{ passCheck }}</p>
    </div>
    <div>
        <button class="roll" v-on:click="roll20()">Roll!</button>
        <p>You Rolled a {{ roll20() }}</p>
    </div>
</div>


JS:

new Vue({
    el: '#exercise',
    data: {
        yourRoll: '10',
        passCheck: '10',
    },
    methods: {
        roll20: function(){
            this.yourRoll = Math.round(Math.random()*19)+1;
            return this.yourRoll;
        },
        newCheck: function(){
            this.passCheck = Math.round(Math.random()*19)+1;
        }
    }
});


在第二段中使用{{roll20()}}时,单击“新挑战”按钮将同时运行roll20()和newCheck()。但是,如果在第二段中使用{{yourRoll}},则不会发生这种情况。

在这两种情况下,请点击“滚动!”仅运行roll20()。

有人可以帮忙解释一下这里发生了什么吗?

这是该问题的代码笔:
Codepen of code

注意:我最终通过使用另一种方法来绕过该问题,但是我仍然想知道为什么发生这种情况:Working Approach

最佳答案

每当DOM更新时,由于以下原因,它将再次运行roll20

<p>You Rolled a {{ roll20() }}</p>


因此,任何触发更新的操作都会因此触发roll20



现在,由于有了模板:

<div><button class="test" v-on:click="newCheck()">New Challenge</button>


我们知道,当您点击New Challenge时,它将调用newCheck方法。



并且由于newCheck方法更改了模板中使用的变量(passCheck):

    newCheck: function(){
        this.passCheck = Math.round(Math.random()*19)+1;
    }


在这里使用:

    <p>Success check is: {{ passCheck }}</p>


更改passCheck将触发DOM更新。 DOM更新将自动调用roll20(由于此答案第一段中所述的原因)。



解决它:

最简单的方法就是不调用模板中的roll20。并且,由于roll20实际上更新了yourRoll属性:

    roll20: function(){
        this.yourRoll = Math.round(Math.random()*19)+1;
        return this.yourRoll;
    },


您可以仅在模板中使用yourRoll而不是roll20()

<p>You Rolled a {{ yourRoll }}</p>


代码笔:https://codepen.io/acdcjunior/pen/PePBeo

08-25 11:18