VueJs 动态 v-on 事件可能吗?

问题描述 投票:0回答:4

是否可以在 VueJS 中设置动态事件?我尝试构建一个动态表单 作为具有可以监听所有内容的输入的组件。这是一个例子:

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>

是否可以设置像

v-on="<variable>:<function>"
这样的动态 v-on 事件?

javascript laravel-5 vuejs2
4个回答
16
投票

从 Vue 2.4.0+ 开始,

v-on
接受对象语法

参考本文档

<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>

1
投票

在 Vue 3 中,您可以使用方括号将 动态参数 传递给

v-on

<input @[item.on]="checkInputParams" />

Vue SFC Playground 示例.


0
投票

尝试:

<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],
        }), {});
    },
  },
};

0
投票

查看这个自定义输入组件。我还通过回调事件函数动态使用事件修饰符(某种)。我将事件名称和回调传递给自定义组件。

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.
© www.soinside.com 2019 - 2024. All rights reserved.