首页 > 解决方案 > 将事件绑定到自定义组件

问题描述

使用 Vue3

我正在创建一个自定义组件,并希望将事件绑定到其中的输入。所以在这种情况下,我想做一些与v-bind="inputProps". 现在$listeners是如何被删除的?正如您可能看到的那样,我无法使用v-bind="$attrs"这些属性,因为这些属性被划分到它们“去”的地方。

我来这里是为了解决问题,但任何关于改进的提示总是一个受欢迎的奖励。

// c-text.vue

<template>
  <input
    v-if="useAsSingleElement"
    v-bind="inputProps"
    :class="['c-text', 'c-text--is-single-element']"
    @input="$emit('input', $event)"
    @blur="$emit('blur')"
    @focus="$emit('focus')">

  <c-form-item-shell
    v-else
    :id="id"
    :is-required="isRequired"
    :label-text="labelText"
    :icon="icon"
    :icon-class="iconClass"
    :errors="errors"
    :information="information">
    <template #element>
      <input
        v-bind="inputProps"
        class="c-text"
        @input="$emit('input', $event.target.value)"
        @blur="$emit('blur')"
        @focus="$emit('focus')">
    </template>
  </c-form-item-shell>
</template>

<script>
import { computed } from 'vue'
import CFormItemShell from '@/components/c-form-item-shell.vue'

export default {
  components: {
    CFormItemShell
  },
  props: {
    useAsSingleElement: { type: Boolean, required: false, default: false },
    name: { type: String, required: true },
    type: { type: String, required: false, default: 'text' },
    placeholder: { type: String, required: false, default: null },
    maxlength: { type: [String, Number], required: false, default: null },
    minxlength: { type: [String, Number], required: false, default: null },
    pattern: { type: String, required: false, default: null },
    readonly: { type: Boolean, required: false, default: false },
    spellcheck: { type: Boolean, required: false, default: false },
    autocomplete: { type: Boolean, required: false, default: true },
    id: { type: String, required: true },
    isRequired: { type: Boolean, required: false, default: false },
    labelText: { type: String, required: false, default: null },
    icon: { type: String, required: false, default: null },
    iconClass: { type: String, required: false, default: null },
    errors: { type: [String, Array], required: false, default: null },
    information: { type: [String, Array], required: false, default: null }
  },
  emits: ['input', 'blur', 'focus'],
  setup (props) {
    const inputProps = computed(() => {
      return {
        id: props.id,
        name: props.name ? props.name : props.id,
        type: props.type,
        placeholder: props.placeholder,
        maxlength: props.maxlength,
        minlength: props.minlength,
        pattern: props.pattern,
        readonly: props.readonly,
        spellcheck: props.spellcheck,
        autocomplete: props.autocomplete ? 'on' : 'off'
      }
    })

    return {
      inputProps
    }
  }
}
</script>

标签: vue.jsvuejs3

解决方案


基于迁移指南

在 Vue 3 的虚拟 DOM 中,事件监听器现在只是属性,前缀on为 ,因此是对象的一部分$attrs,因此$listeners已被删除。

所以只需传递您的事件,例如onClickonBlur...和

export default {
  inheritAttrs: false
}

推荐阅读