Vue ctrl+s 事件侦听器未触发

Mar*_*arc 2 vue.js

我的应用程序对话框应该响应“Ctrl+S”以获取保存功能并取消默认浏览器保存事件。

<div
  @keyup.83="doSave"
  @keyup.ctrl.83="doSave"
  @keyup.alt.83="doSave"
  tabindex="0">
Run Code Online (Sandbox Code Playgroud)

doSave 事件在按下 's'(和alt+s)而不是按下时触发ctrl+s

为什么ctrl+s没有被解雇?

奖金问题:有没有办法preventDefault不用编码?不知何故,应该可以添加,.once但文档含糊不清。

https://codepen.io/cawoodm/pen/qvgxPL

Sum*_*ai8 10

你的问题里有几个问题,我来一一回答:

为什么 ctrl+s 没有被触发?

几个原因。您正在使用该keyup事件,而浏览器开始在 keydown 事件上保存页面。因此,您的 keyup 事件永远不会被触发。

对于要在您的 div 上注册的任何事件,您的 div必须具有焦点,否则该事件将不会来自该元素,而是来自(大概)主体。

有没有办法在不编码的情况下防止默认?

是的。将prevent修饰符添加到您的事件中。以同样的方式,您可以使用once在事件触发一次后取消注册事件,stop使用stopPropagation()passive明确不停止传播。你会使用这样的:@keydown.ctrl.83.prevent="saveMe"

我如何让这个工作?

如果您对用户在保存之前必须聚焦元素并以其他方式获得默认行为感到满意,请使用以下内容:

<div
  id="app"
  tabindex="0"
  @keydown.ctrl.83.prevent.stop="saveInsideComponent"
>
  <!-- -->
</div>
Run Code Online (Sandbox Code Playgroud)

否则,这是注册您自己的事件侦听器有用的少数时刻之一。只需确保在您的组件被销毁之前将其删除,否则您将有一个流氓事件侦听器在其他组件上抛出错误 + 需要处理的内存泄漏。

  mounted() {
    document.addEventListener("keydown", this.doSave);
  },

  beforeDestroy() {
    document.removeEventListener("keydown", this.doSave);
  },

  methods: {
    doSave(e) {
      if (!(e.keyCode === 83 && e.ctrlKey)) {
        return;
      }

      e.preventDefault();
      console.log("saving from DOM!");
    },
  }
Run Code Online (Sandbox Code Playgroud)

编辑 Vue + Vuex + VueRouter 模板


小智 7

@Sumurai8 的答案很好,但我会通过检查 if e.metaKeyis == true 来添加对苹果设备的支持。代码如下所示:

      mounted() {
        document.addEventListener("keydown", this.doSave);
      },
    
      beforeDestroy() {
        document.removeEventListener("keydown", this.doSave);
      },
    
      methods: {
        doSave(e) {
          if (!(e.keyCode === 83 && (e.ctrlKey || e.metaKey))) {
            return;
          }
    
          e.preventDefault();
          console.log("saving from DOM!");
        },
      }
Run Code Online (Sandbox Code Playgroud)