简体   繁体   English

在窗口上添加 Vue.js 事件

[英]Add Vue.js event on window

Vue.js allow apply event on element: Vue.js 允许在元素上应用事件:

<div id="app">
   <button @click="play()">Play</button>
</div>

But how to apply event on window object?但是如何在window对象上应用事件? it is not in DOM.它不在 DOM 中。

for example:例如:

<div id="app">
  <div @mousedown="startDrag()" @mousemove="move($event)">Drag me</div>
</div>

in this example, how to listen mousemove event on window ?在这个例子中,如何在window上监听 mousemove 事件?

You should just do it manually during the creation and destruction of the component您应该在组件的创建和销毁期间手动执行此操作

...
created: function() {
  window.addEventListener('mousemove',this.move);
},
destroyed: function() {
  window.removeEventListener('mousemove', this.move);
}
...

Jeff's answer is perfect and should be the accepted answer.杰夫的回答是完美的,应该是公认的答案。 Helped me out a lot!帮了我很多忙!

Although, I have something to add that caused me some headache.虽然,我有一些事情要补充,这让我有些头疼。 When defining the move method it's important to use the function() constructor and not use ES6 arrow function => if you want access to this on the child component.在定义move方法时,重要的是使用function()构造函数而不是使用 ES6 箭头函数=>如果您想在子组件上访问this this doesn't get passed through to arrow functions from where it's called but rather referrers to its surroundings where it is defined. this不会从它被调用的地方传递给箭头函数,而是引用它定义它的周围环境。 This is called lexical scope.这称为词法范围。

Here is my implementation with the called method (here called keyDown instead of move ) included:这是我使用被调用方法(此处称为keyDown而不是move )的实现:

export default {
  name: 'app',
  components: {
    SudokuBoard
  },
  methods: {
    keyDown: function () {
      const activeElement = document.getElementsByClassName('active')[0]
      if (activeElement && !isNaN(event.key) && event.key > 0) {
        activeElement.innerHTML = event.key
      }
    }

  },

  created: function () {
    window.addEventListener('keydown', this.keyDown)
  },

  destroyed: function () {
    window.removeEventListener('keydown', this.keyDown)
  }
}

To be extra clear, The method below doesn't have access to this and can't for example reach the data or props object on your child component.更清楚的是,下面的方法无法访问this ,例如无法访问子组件上的 data 或 props 对象。

methods: { 
    keyDown: () => {
      //no 'this' passed. Can't access child's context 
      }

You can also use the vue-global-events library.您还可以使用vue-global-events库。

<GlobalEvents @mousemove="move"/>

It also supports event modifiers like @keydown.up.ctrl.prevent="handler" .它还支持事件修饰符,如@keydown.up.ctrl.prevent="handler"

This is for someone landed here searching solution for nuxt.js :这是给在这里搜索nuxt.js解决方案的nuxt.js

I was creating sticky header for one of my projects & faced issue to make window.addEventListener work.我正在为我的一个项目创建粘性标题,并面临使window.addEventListener工作的问题。

First of all, not sure why but window.addEventListener doesn't work with created or beforeCreate hooks, hence I am using mounted .首先,不确定为什么但window.addEventListener不适用于createdbeforeCreate钩子,因此我使用的是mounted

<template lang="pug">
  header(:class="{ 'fixed-header': scrolled }")
    nav menu here
</template>

<script>
export default {
  name: 'AppHeader',

  data() {
    return { scrolled: false };
  },

  mounted() {
    // Note: do not add parentheses () for this.handleScroll
    window.addEventListener('scroll', this.handleScroll);
  },

  methods: {
    handleScroll() {
      this.scrolled = window.scrollY > 50;
    },
  },
};
</script>

I found that using window.addEventListener no longer worked as I expected with Vue 3. It appears that the function is wrapped by Vue now.我发现在 Vue 3 中使用window.addEventListener不再像我预期的那样工作。看来该函数现在被 Vue 包装了。 Here's a workaround:这是一个解决方法:

...
created()
{
  document.addEventListener.call(window, "mousemove", event =>
  {
    ...
  });
}
...

The important part is document.addEventListener.call(window , what we're doing is to take the unwrapped addEventListener from document and then call it on the window Object.重要的部分是document.addEventListener.call(window ,我们正在做的是从document取出展开的addEventListener ,然后在window对象上调用它。

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

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