Is it possible to set dynamic on event in VueJS? I try to build a dynamic form as component with inputs that can listen on everything. Here an example:
import Vue from 'vue';
let formItems = {
{type: 'checkbox', id: 'some-id', on:'change', model: 'someId'},
{type: 'url', id: 'another-id', on:'keyup', model:'anotherId'},
};
let params = {
someId: true,
anotherId: '',
};
new Vue({
el: '#app',
data: {
formItems: formItems,
params: params,
},
methods: {
checkInputParams(e) {
e.preventDefault();
// Do some stuff.
}
}
});
<script src=".3.4/vue.js"></script>
<div id="app">
<div class="form-group" v-for="item in formItems">
<input type="checkbox" <!-- Also need a workaround for dynamic type and v-model -->
:id="item.id"
:class="(item.class ? item.class : '')"
:title="(item.title ? item.title : '')"
:placeholder="(item.placeholder ? item.placeholder : '')"
:autocomplete="(item.autocomplete ? item.autocomplete : false)"
:disabled="(item.disabled ? item.disabled : false)"
:max="(item.max ? item.max : '')"
:min="(item.min ? item.min : '')"
:maxlength="(item.maxLength ? item.maxLength : '')"
:multiple="(item.multiple ? item.multiple : '')"
:name="(item.name ? item.name : '')"
:readonly="(item.readonly ? item.readonly : false)"
:required="(item.required ? item.required : false)"
v-on="{{ item.on }}:checkInputParams" <!-- Here I try the dynamic v-on -->
v-model="params[item.model]"/>
</div>
</div>
Is it possible to set dynamic on event in VueJS? I try to build a dynamic form as component with inputs that can listen on everything. Here an example:
import Vue from 'vue';
let formItems = {
{type: 'checkbox', id: 'some-id', on:'change', model: 'someId'},
{type: 'url', id: 'another-id', on:'keyup', model:'anotherId'},
};
let params = {
someId: true,
anotherId: 'http://www.example.com',
};
new Vue({
el: '#app',
data: {
formItems: formItems,
params: params,
},
methods: {
checkInputParams(e) {
e.preventDefault();
// Do some stuff.
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.js"></script>
<div id="app">
<div class="form-group" v-for="item in formItems">
<input type="checkbox" <!-- Also need a workaround for dynamic type and v-model -->
:id="item.id"
:class="(item.class ? item.class : '')"
:title="(item.title ? item.title : '')"
:placeholder="(item.placeholder ? item.placeholder : '')"
:autocomplete="(item.autocomplete ? item.autocomplete : false)"
:disabled="(item.disabled ? item.disabled : false)"
:max="(item.max ? item.max : '')"
:min="(item.min ? item.min : '')"
:maxlength="(item.maxLength ? item.maxLength : '')"
:multiple="(item.multiple ? item.multiple : '')"
:name="(item.name ? item.name : '')"
:readonly="(item.readonly ? item.readonly : false)"
:required="(item.required ? item.required : false)"
v-on="{{ item.on }}:checkInputParams" <!-- Here I try the dynamic v-on -->
v-model="params[item.model]"/>
</div>
</div>
Is it possible to set a dynamic v-on event like v-on="<variable>:<function>"
?
4 Answers
Reset to default 16From Vue 2.4.0+, v-on
accepts an object syntax
Refer this documentation
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>
In Vue 3, you can pass a dynamic argument to v-on
with square brackets.
<input @[item.on]="checkInputParams" />
Vue SFC Playground example.
Try:
<button v-on="buttonListeners"></button>
// ...
{
data() {
return {
listeners: {
'mousedown': 'doThis',
},
};
},
computed: {
buttonListeners() {
return Object
.entries(this.listeners)
.reduce((acc, [eventName, methodName]) => ({
...acc,
[eventName]: this[methodName],
}), {});
},
},
};
Check out this custom input component. I'm also using event modifiers(kind of) dynamically through the callback event function. I'm passing the event name and callback to the custom component.
BaseFormTextInput.vue
<script setup>
import { computed } from 'vue'
const props = defineProps(['modelValue', 'label', 'id', 'type', 'event', 'eventHandler'])
const emit = defineEmits(['update:modelValue'])
const value = computed({
get() {
return props.modelValue
},
set(value) {
emit('update:modelValue', value)
}
})
</script>
<template>
<div class="o-form__textControl">
<label :for="id" class="o-form__label">{{ label }}</label>
<slot name="input">
<input @[event]="eventHandler($event)" :type="type" name="email" :id="id" v-model="value" />
</slot>
</div>
</template>
Parent.vue
<script setup>
import { reactive, ref } from 'vue'
import BaseFormTextInput from '../components/BaseFormTextInput.vue'
const skills = reactive([])
const tempSkill = ref('')
const addSkill = (e) => {
if (e.key === ',' && e.altKey === true) {
if (!skills.includes(this.tempSkill)) {
skills.push(this.tempSkill)
}
this.tempSkill = ''
}
}
</script>
<template>
<BaseFormText
label="skills (press alt + comma to add):"
id="skills"
v-model="registerModel.tempSkill"
:event-handler="addSkill"
event="keyup"
/>
</template.