Vue实例中手动监听鼠标事件

Manually listen for mouse event in Vue instance

我试图从组件的子组件中侦听鼠标事件,但我没有触发该事件。当我在 html 中收听事件时它有效,但在

中无效

如您所见,这是有效的:

Vue.config.devtools = false;
Vue.config.productionTip = false;

new Vue({
  el: '#mouse',
  data: {
    message: 'Hover Me!'
  },
  methods: {
    mouseover: function() {
      this.message = 'Good!'
    },
    mouseleave: function() {
      this.message = 'Hover Me!'
    }
  }
});
body {
  background: #333;
}

body #mouse {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: block;
  width: 280px;
  height: 50px;
  margin: 0 auto;
  line-height: 50px;
  text-align: center;
  color: #fff;
  background: #007db9;
}

body #mouse a {
  display: block;
  width: 100%;
  height: 100%;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="mouse">
  <a @mouseover="mouseover" @mouseleave="mouseleave">
    {{message}}
  </a>
</div>

这个不行,因为事件监听是在代码中完成的。

Vue.config.devtools = false;
Vue.config.productionTip = false;

new Vue({
  el: '#mouse',
  data: {
    message: 'Hover Me!'
  },
  methods: {
    mouseover: function() {
      this.message = 'Good!'
    },
    mouseleave: function() {
      this.message = 'Hover Me!'
    },
    mounted() {
      this.$on('mouseleave', this.mouseleave);
    }
  }
});
body {
  background: #333;
}

body #mouse {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: block;
  width: 280px;
  height: 50px;
  margin: 0 auto;
  line-height: 50px;
  text-align: center;
  color: #fff;
  background: #007db9;
}

body #mouse a {
  display: block;
  width: 100%;
  height: 100%;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="mouse">
  <a @mouseover="mouseover">
    {{message}}
  </a>
</div>

从组件本身而不是在 html 中手动监听 mouseleave 事件的正确方法是什么?

在第二个片段中,mounted 钩子函数应该在方法之外,这不会解决问题vm.$on 函数用于自定义事件不适用于 clickmouseleave 等原生事件,如 here 所述:

如果你这样称呼:

 vm.$on('test', function (msg) {
    console.log(msg)
  })

您应该在某处有如下代码:

 vm.$emit('test', 'hi')

由于您无法使用 this.$on 方法,我建议您使用 ref 的以下解决方案,方法是将 ref 属性添加到您的 a 元素,方法是link 或任何你想要的,并在已安装的挂钩中添加以下代码:

    this.$refs.link.addEventListener('mouseleave', () => {
      this.mouseleave()
    }, false);

Vue.config.devtools = false;
Vue.config.productionTip = false;

new Vue({
  el: '#mouse',
  data: {
    message: 'Hover Me!'
  },
  methods: {
    mouseover: function() {
      this.message = 'Good!'
    },
    mouseleave: function() {
      this.message = 'Hover Me!'
    }
  },
  mounted() {
    this.$refs.link.addEventListener('mouseleave', () => {
      this.mouseleave()
    }, false);

  }
});
body {
  background: #333;
}

body #mouse {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: block;
  width: 280px;
  height: 50px;
  margin: 0 auto;
  line-height: 50px;
  text-align: center;
  color: #fff;
  background: #007db9;
}

body #mouse a {
  display: block;
  width: 100%;
  height: 100%;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>

<div id="mouse">
  <a @mouseover="mouseover" ref="link">
    {{message}}
  </a>
</div>