I am trying to listen to a mouse event in a child component from the component, but I don't get the event being fired. It works when I listen for the event in html, but not
This works as you can see:
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>
This one doesn't work because the event listening is done in code.
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>
What is the correct way of manually listening for mouseleave
event from the component itself rather than in the html?
In the second snippet the mounted
hook function should be outside of methods, this will not solve the problem, and vm.$on
function is used for custom event not for native ones like click
and mouseleave
, like explained here
:
if you call this :
vm.$on('test', function (msg) {
console.log(msg)
})
You should have a code like the following one somewhere :
vm.$emit('test', 'hi')
Since you're not able to use this.$on
method, i recommend you the following solution using ref
by adding ref
attribute to your a
element by giving link
or whatever you want and in the mounted hook add the following code:
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>