Reputation: 4091
I want to create a component that wraps a textarea
element. Its function is to add custom functionality and custom styling, but I don't want it to be scoped in its own scope - rather, the parent should be able bind to regular events like input
.
Example of what is needed, but will not work (problem is highlighted in parent.vue
):
area.vue:
<template>
<textarea rows="1"></textarea>
</template>
<script>
export default {
mounted() {
// do something...
}
}
</script>
<style scoped>
textarea {
height: 100%;
}
</style>
parent.vue:
<template>
<area @input="doSomething"></area>
</template>
<script>
import Area from "./area.vue"
export default {
methods: {
doSomething(){
// NOT TRIGGERED!
// `input` event is not passed over to parent scope
}
},
components: {
Area
}
}
</script>
I do not want to explicitly write in this.$emit
calls into the component.
Upvotes: 4
Views: 2812
Reputation: 3522
You only need to add .native
to @input
.
Vue's v-on
/@
, when used on a component (without .native
), only listens to custom events declared by emit
.
Upvotes: 8
Reputation: 746
Unfortunately you can't do this, but you can cheat and get pretty close.
mounted() {
var self = this;
Object.keys(Event.prototype).forEach(function(ev) {
self.$refs.text.addEventListener(ev.toLowerCase(), function(d) {
self.$emit(ev.toLowerCase(), d);
console.log("emitting", ev, d);
})
})
}
With this you get access to mousedown
, mouseup
, mouseover
, mouseout
, mousemove
, mousedrag
, click
, dblclick
, keydown
, keyup
, keypress
, dragdrop
, focus
, blur
, select
and change
events. Then in your parent template...
<my-textarea @keyup="update()" @change="somethingElse()"></my-textarea>
Here's the fiddle https://jsfiddle.net/rdjjpc7a/371/
Upvotes: 2
Reputation: 6574
you can pass methods from the parent to the child as props, i.e.
parent
<area :do-something="doSomething"></area>
child
# template
<textarea rows="1" @input="doSomething"></textarea>
# script
export default {
props: ['doSomething'],
...
Upvotes: 2