调用vuejs方法的jQuery全局keypress事件方法没有按预期工作。为什么呢?

时间:2017-10-27 13:58:51

标签: javascript jquery vue.js vuejs2

我有一个可以显示几个html样式对话框的网页。我希望只在一个地方有代码可以感知到按下了回车键,并调用与通过单击对话框的确定​​按钮调用相同的方法。这允许访问者在对话框中按Enter键关闭它,而不必单击“确定”按钮。非常简单的东西。

我使用jQuery创建一个全局keydown处理程序,它查找enter键并调用vuejs dlogClose方法。我在下面创建了一个最小版本。在现实生活中,会有多个对话框和更复杂的代码,以便为特定对话框找到合适的dlogClose方法。但是我已经删除了这个逻辑来创建一个Vue不按预期运行的最小代码示例。

单击按钮以打开对话框。然后单击“确定”按钮。它将显示一条警告说" dlogClose名为"然后它将关闭对话框。完全符合预期。

然后单击按钮再次打开对话框。这次按回车键。 jQuery全局事件处理程序将看到enter键并调用相同的dlogClose方法。该方法将显示一条警告说" dlogClose调用"如预期但它不会关闭对话框!什么?这是完全出乎意料的行为。

你能解释为什么这种行为有效吗?或者这是某种vue库错误?



var app = new Vue({
    el: '#app',
    data: {
        dlogVisible: false
    },
    methods: {
        dlogClose: function () {
            alert("dlogClose called");
            app.dlogVisible = false;
        }

    },
    created: function () {
        $(document).keypress(function (e) {
            if (e.which == 13) {
                app.dlogClose();
            }
        });
    }
});

.dlog{
    height:200px; width:200px; border: solid 1px gray; 
    padding: 20px; box-shadow: 0px 3px 15px gray;
    position: absolute; top:40px; left:40px; background-color:white
}

    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="https://unpkg.com/vue@2.2.5/dist/vue.min.js"></script>

    <div>Global Enter Key Example</div>
    <br />
    <div id="app">
        <div class="dlog" v-if="dlogVisible">
            Pressing enter calls same method as clicking OK button<br />
            <br />
            <button type="button" v-on:click="dlogClose()">OK</button>
        </div>

        <button type="button" v-on:click="dlogVisible=true;">Open Dialog</button>
    </div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

这里的问题是在对话框打开时按下回车键也会触发打开的对话框按钮。所以从本质上讲,对话框已关闭并立即重新打开。使用preventDefault来阻止这种情况发生。

$(document).keypress(function (e) {
  e.preventDefault()
  if (e.which == 13) {         
    app.dlogClose();
  }
});

以下是更新的代码。

&#13;
&#13;
var app = new Vue({
    el: '#app',
    data: {
        dlogVisible: false
    },
    methods: {
        dlogClose: function () {
            alert("dlogClose called");
            app.dlogVisible = false;
        }

    },
    created: function () {
        $(document).keypress(function (e) {
            e.preventDefault()
            if (e.which == 13) {
            
                app.dlogClose();
            }
        });
    }
});
&#13;
.dlog{
    height:200px; width:200px; border: solid 1px gray; 
    padding: 20px; box-shadow: 0px 3px 15px gray;
    position: absolute; top:40px; left:40px; background-color:white
}
&#13;
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="https://unpkg.com/vue@2.2.5/dist/vue.min.js"></script>

    <div>Global Enter Key Example</div>
    <br />
    <div id="app">
        <div class="dlog" v-if="dlogVisible">
            Pressing enter calls same method as clicking OK button<br />
            <br />
            <button type="button" v-on:click="dlogClose()">OK</button>
        </div>

        <button type="button" v-on:click="dlogVisible=true;">Open Dialog</button>
    </div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您可以在最顶层页面组件(App组件)中的created()方法中创建jQuery事件侦听器。在该顶级应用程序组件中,只要满足您指定的条件,就可以在每次触发输入按钮时触发方法。为简单起见,您可以增加一个vuex状态计数器或其他东西。无论您拥有哪种子组件,都可以监视计数器的变化并做出相应的反应(同样根据您设置的条件)。我对调度知之甚少,但这可能是另一种调查途径。

相关问题