我创建了一个自定义输入组件。
我需要让@blur从vee验证表单到我的自定义输入组件。
它在正常的html输入标记中工作得很好。我不知道如何将@blur传递到自定义输入组件中。
示例1正确工作,它在模糊输入后触发验证。
<template>
<form @submit="onSubmit">
<input @blur="emailBlur" v-model="email" type="text" autocomplete="off" name="email" placeholder="email">
<button type="submit" :disabled="isSubmitting">Submit</button>
</form>
</template>使用我的自定义输入组件的示例2:
// src/components/Input.vue
<template>
<div class="mt-2">
<label :for="name" class="h5">Name</label>
<input
:type="type"
:value="modelValue"
@change="$emit('update:modelValue', $event.target.value)"
:id="name"
:placeholder="placeholder"
/>
</div>
</template>
<script>
export default {
name: 'Input',
props: ["modelValue", 'name', 'type', 'placeholder'],
setup(props) {
console.log('props :>> ', props); // not receive the @blur
}
}
</script>父组件(App.vue):
<template>
<form>
<Input @blur="emailBlur" v-model="email" type="text" name="email" placeholder="Custom input email" />
<button type="submit" :disabled="isSubmitting">Submit</button>
</form>
</template>
export default {
name: 'App',
components: {
Input
},
setup() {
// the vee validation values v-model to template
}
}发布于 2021-10-07 15:46:08
从父组件将处理程序作为道具发送不是一个好的做法,而是需要从子组件触发处理程序(出现在父组件中)。通过这样做,您将有一个优势,您可以根据不同父组件中的需求绑定不同的模糊处理程序。
要做到这一点,您可以遵循以下方法
自定义输入组件
// src/components/Input.vue
<template>
<div class="mt-2">
<label :for="name" class="h5">Name</label>
<input
:type="type"
:value="modelValue"
@change="$emit('update:modelValue', $event.target.value)"
:id="name"
:placeholder="placeholder"
@blur="$emit('blur')" //Change added
/>
</div>
</template>
<script>
export default {
name: 'Input',
props: ["modelValue", 'name', 'type', 'placeholder'],
emits: ['blur', 'update:modelValue'], // change added
}
</script>注:
对于所有没有参数的v-模型,请确保分别将道具和事件名称更改为modelValue和update:modelValue。
例如:
Parent.vue
<ChildComponent v-model="pageTitle" />在Child.vue中,它应该是
export default {
props: {
modelValue: String // previously was `value: String`
},
emits: ['update:modelValue'],
methods: {
changePageTitle(title) {
this.$emit('update:modelValue', title) // previously was `this.$emit('input', title)`
}
}
}发布于 2021-10-07 17:40:00
您所创建的组件通常称为“透明包装器”组件。您想从这个包装器中得到的是,几乎所有的方式都表现为普通的input组件,这样组件的用户就可以使用它了,就像普通的input一样(但它不是)。
在您的示例中,您希望将@blur事件侦听器附加到包装器中。但问题是,blur是原生浏览器事件,即不是Vue事件。
当为发射选项中未指定的事件(或v-bind --组件的props中未指定的属性)将事件侦听器放置在组件上时,Vue将将其视为非支持属性。这意味着它获取所有此类事件侦听器和非支持属性,并将其放置在组件的根节点(在您的示例中为div)上。
但幸运的是,有一种方法可以告诉Vue“嘿,不要把那些自动放在根目录上,我知道该放哪了。”
inheritAttrs: false 选项input -使用v-bind="$attrs"。现在您甚至可以删除一些道具--例如placeholder (如果您愿意),因为如果您直接在组件上使用它,Vue将它放在input上,这就是您想要的.
也是处理@change事件的最佳方式--您的组件允许指定type和不同的输入类型有不同的事件。。它的好处不是显式地传递value和绑定事件,而是使用v-model和computed (参见下面的示例)。
const app = Vue.createApp({
data() {
return {
text: ""
}
},
methods: {
onBlur() {
console.log("Blur!")
}
}
})
app.component('custom-input', {
inheritAttrs: false,
props: ["modelValue", 'name', 'type'],
emits: ['update:modelValue'],
computed: {
model: {
get() { return this.modelValue },
set(newValue) { this.$emit('update:modelValue', newValue) }
}
},
template: `
<div class="mt-2">
<label :for="name" class="h5">{{ name }}:</label>
<input
:type="type"
v-model="model"
:id="name"
v-bind="$attrs"
/>
</div>
`
})
app.mount("#app")<script src="https://unpkg.com/vue@3.2.19/dist/vue.global.js"></script>
<div id='app'>
<custom-input type="text" name="email" v-model="text" placeholder="Type something..." @blur="onBlur"></custom-input>
<pre>{{ text }}</pre>
</div>
https://stackoverflow.com/questions/69483447
复制相似问题