我正在尝试为Vue.js中的<input/>
元素创建包装器组件。
组件:
<template>
<div>
<input v-bind="$attrs" :value="value" @input="input" />
...
</div>
<template>
Vue.component("my-input", {
inheritAttrs: false,
props: ['value'],
methods: {
input($event): void {
this.$emit("input", $event.target.value)
}
}
})
用法:
<my-input v-model="myModel" />
这似乎很好。通过输入事件处理程序,通过发出目标元素值来更新模型。
但是,现在我正在尝试将此组件与一些现有代码一起使用:
<my-input v-model="myModel2" @input="something = $event.target.value" />
这是我在$emit("input")
事件上遇到麻烦的地方。我收到以下错误:
无法读取未定义的属性“值”
因此,我的$emit
发出了值,现在现有的@input="something..."
事件处理程序无法正确引用$event
。
如果我将组件的input
方法更改为发出$event
而不是$event.target.value
,则新代码似乎可以正常工作,但是模型无法得到更新被更新为 InputEvent 而不是实际的 value 。
我不确定该怎么做。
答案 0 :(得分:1)
尝试
<my-input v-model="myModel2" @input="value => something = value" />
答案 1 :(得分:1)
当您$emit('input')
并将值绑定到文本输入的v-model
时,<input>
的值将更新为您发出的任何值。对于$emit('input', $event.target.value)
,它是您发出的<input>
中文本的值。该值将在父级中被拦截,就像v-model
那样:<my-input :value="inputValue" @input="inputValue = $event">
这意味着<input
>的值将绑定回到<input>
(有效地导致输入中的值不变)。但是,如果您$emit('input', $event)
,则v-model
仍将捕获传递的任何值,并使用它更新<input>
的值。如您所说,在这种情况下,它将是实际的输入事件对象。
如果您不想使用与模型相关的input
事件,则可以始终使用custom v-model
event。然后,您将能够$emit('input', $event)
而不会影响v模型的值,而是从$emit('custom-event', $event.target.value)
答案 2 :(得分:1)
const MyInput = Vue.extend({
name: 'MyInput',
template: '#ins',
data(){return{valid: true}},
methods: {validate(ev){this.valid = ev.target.value.length < 1 ;this.$listeners.input(ev)}}
})
const App = Vue.extend({
components: {
MyInput
},
template: '#myinput',
data(){return{val: 'test'}},
methods: {ins(ev){console.log(ev.target.value)}}
})
new Vue({
name: 'root',
render: h => h(App)
}).$mount("#app");
input {background: red}
.valid{background:green !important}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>
<template id="ins">
<input v-bind="$attrs" @input="validate" :class="{valid:valid}"/>
</template>
<template id="myinput">
<my-input v-model="val" @input="ins" />
</template>