我有一个计算属性,我将其用作输入的v-model
。我这样写它是为了获得反应性——这调用了我的setText
Vuex 动作,然后我可以用我的 gettertext
获得它。它看起来像这样:
text: {
get() {
return this.text;
},
set(value) {
this.setText(value);
},
},
我在输入中使用它,如下所示:
<input class="input" type="text" v-model="text" />
这很好用。现在,我已经将有问题的input
放入我使用的单独组件中。这意味着我必须将text
v模型作为道具传递,我用:model.sync
这样做,如下所示:
<myInput :model.sync="text"/>
在myInput
组件中,我使用这样的道具:
<input class="input" id="search-order" type="text" :value="model" @input="$emit('update:model', $event)">
但这似乎根本不起作用,每当我输入输入时,输入都会说:[object InputEvent]
,如果我尝试查看和model
的值,它就会{isTrusted: true}
.我假设这是因为我在计算属性上的获取者和设置器。如何将这些传递给子组件?
您可以在自定义组件中支持v-model
指令,而不是使用.sync
修饰符。v-model
是value
道具和input
事件的语法糖。
要支持v-model
只需确保您的自定义组件具有value
prop,并发出具有新值的input
事件:this.$emit('input', event.target.value)
。
这是我使用的<BaseInput>
组件的示例,它是用TypeScript编写的:
<template>
<input
:type="type"
:value="value"
class="input"
v-on="listeners"
>
</template>
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
name: 'BaseInput',
props: {
type: {
type: String,
default: 'text',
},
value: {
type: [String, Number],
default: '',
},
lazy: {
type: Boolean,
default: false,
},
number: {
type: Boolean,
default: false,
},
trim: {
type: Boolean,
default: false,
},
},
computed: {
modelEvent(): string {
return this.lazy ? 'change' : 'input'
},
parseModel(): (value: string) => string | number {
return (value: string) => {
if (this.type === 'number' || this.number) {
const res = Number.parseFloat(value)
// If the value cannot be parsed with parseFloat(),
// then the original value is returned.
return Number.isNaN(res) ? value : res
} else if (this.trim) {
return value.trim()
}
return value
}
},
listeners(): Record<string, Function | Function[]> {
return {
...this.$listeners,
[this.modelEvent]: (event: HTMLElementEvent<HTMLInputElement>) =>
this.$emit(this.modelEvent, this.parseModel(event.target.value)),
}
},
})
</script>
您可以像这样使用它:
<BaseInput v-model="text" />