简体   繁体   English

事件阻止默认在 VueJS 实例中不起作用

[英]event prevent default not working within VueJS instance

I'm trying to disable a form submission when the enter key is pressed.我试图在按下回车键时禁用表单提交。 The approaches I've tried are listed below with the code and example demo.下面列出了我尝试过的方法以及代码和示例演示。

EXAMPLE OF PROBLEM HERE这里的问题示例

Desired outcome: Focus on the input, press down -> down -> enter and it should log the index of the record you have selected and stop there.期望的结果:专注于输入,按下 -> 向下 -> 输入,它应该记录你选择的记录的索引并停在那里。

What's actually happening: It logs as expected, but then reloads the page immediately as the form submits.实际发生了什么:它按预期进行记录,但随后在表单提交时立即重新加载页面。

HTML HTML

<form action="/some-action" @submit.stop.prevent="prevent">
  <div class="auto-complete" v-cloak>
    <div class="ico-input">
      <input type="text" name="search" placeholder="Enter text" @keyup.prevent="handleKeypress">
    </div>
    <ul class="raw auto-complete-results">
      <li v-for="r in results" @click="loadSelection($index)" v-bind:class="{'selected': selectedIndex == $index}"><span>{{ r.name }}</span></li>
    </ul>
  </div>
</form>

JS JS

var autocomplete = new Vue({
  el: '.auto-complete',
  data: {
    results: [{name: 'swimming1'}, {name: 'swimming2'}, {name: 'swimming3'}, {name: 'swimming4'}, {name: 'swimming5'}, ],
    selectedIndex: -1,
  },
  methods: {
    handleKeypress: function(event) {
      event.preventDefault();
      event.stopPropagation();

      var key = event.which;

      if ([38, 40].indexOf(key) > -1) //handle up down arrows.
        this.arrowNavigation(key);

      else if (key == 13) //handle enter keypress
        this.loadSelection(this.selectedIndex);

      return false;
    },

    arrowNavigation: function(key, target) {
      if (key == 38) //up
        this.selectedIndex = this.selectedIndex - 1 < 0 ? 0 : this.selectedIndex - 1;
      if (key == 40) //down
        this.selectedIndex = (this.selectedIndex + 1) > (this.results.length - 1) ? 0 : this.selectedIndex + 1;
    },

    loadSelection: function(index) {

      if (index < 0 || index > this.results.length)
        return false;

      var selection = this.results[index];
      console.log("loading selection", index,selection);
    },

    prevent: function(event) {
      event.preventDefault();
      event.stopPropagation();
      return false;
    },
  }
})

I've tried various syntax approaches on both form/input (switching submit for keyup on the input)我已经在表单/输入上尝试了各种语法方法(在输入上切换keyup submit

  • v-on:submit="prevent" v-on:submit="阻止"
  • @submit @提交
  • @submit.stop @提交.停止
  • @submit.prevent @提交.prevent
  • @submit.stop.prevent="prevent" @submit.stop.prevent="预防"

I've also tried calling the following from with in the 2 event handlers aswell as returning false from them both.我还尝试在 2 个事件处理程序中使用 with 调用以下内容,并从它们中返回 false。

  • event.preventDefault()事件.preventDefault()
  • event.stopPropagation()事件.stopPropagation()

The form still triggers a page reload no matter what I try.无论我尝试什么,表单仍然会触发页面重新加载。 I can't see anything obviously wrong so I turn to stackoverflow to guide my eyes.我看不出有什么明显的错误,所以我转向 stackoverflow 来指导我的眼睛。

Thanks谢谢

This Answer to another question suggests that forms with a single input element always get submitted, not matter what you do. 这回答另一个问题表明,与单独的输入元素的形式总是得到提交的,不管你做什么。

And indeed adding another input (and hiding it) helped. 确实添加另一个输入(并隐藏它)有帮助。

https://jsfiddle.net/Linusborg/Lbq7hf1v/1/ https://jsfiddle.net/Linusborg/Lbq7hf1v/1/

<div class="ico-input">
  <input type="text" name="search" placeholder="Enter text" @keyup.prevent="handleKeypress">
  <input type="text" hidden style="display:none;">
</div>

Browsers are stupid. 浏览器是愚蠢的。

Note that, anything outside of the el that you use to reference your Vue instance will not be recognized by vue no matter how correctly you define your event modifiers on your elements. 请注意,无论您在元素上定义事件修饰符的方式如何,vue都无法识别用于引用Vue实例的el之外的任何内容。

In your example you are referring to your Vue instance through the .auto-complete element which is a child of the form element which the submit event is bound to by default. 在您的示例中,您通过.auto-complete元素引用您的Vue实例,该元素是默认情况下绑定submit事件的form元素的子元素。 Any event modifiers added to your form will never take effect. 添加到form任何事件修饰符都不会生效。 Try wrapping all your HTML in a div and reference vue through that, like so: 尝试将所有HTML包装在div中并通过它引用vue,如下所示:

HTML HTML

<div id="app">
    <!-- HTML/Vue Directives/Mustache here -->
    <form action="/some-action" @submit.stop.prevent="prevent"> 
        ... rest of your code ...
    </form>
</div>

JS: JS:

var autocomplete = new Vue({
    el: '#app',
    data: { 
        ... rest of your js code ...
})

Also Vue devtools can be very useful when debugging such situations. 在调试这种情况时, Vue devtools也非常有用。

Try this!试试这个!

<form @submit.prevent>

Works for Vue2适用于 Vue2

Try @keydown.enter.prevent I was having the same problem but I was using keyup尝试@keydown.enter.prevent 我遇到了同样的问题,但我使用的是 keyup

<input type="text" @keydown.enter.prevent="doSomething" />

You don't have to have a method either if you just want to stop the form from submitting just put @keydown.enter.prevent without a method.如果你只是想停止提交表单,你也不必有方法,只需将 @keydown.enter.prevent 放在没有方法的情况下。

<input type="text" @keydown.enter.prevent />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM